Repository: runelite/runelite
Pull request #17203 (2023-11-17 20:48:14)

prayer: fix dragging prayers when plugin is disabled
When prayer reordering is enabled and the prayer plugin gets disabled, the ``drag`` and ``drag on`` flag are not removed on plugin shutdown. Thus, the prayers remain draggable.

Before:
https://github.com/runelite/runelite/assets/7929021/7af73acb-74a5-4187-bc80-af0d370dbf2c

After:
https://github.com/runelite/runelite/assets/7929021/7efc3527-ec39-4178-8399-417c1469d146

Alternatively add something like this and invokeLater it on shutDown on the clientThread:

```
	if (isInterfaceOpen(InterfaceID.PRAYER))
	{
		var prayerbook = client.getVarbitValue(Varbits.PRAYERBOOK);
		var prayerBookEnum = getPrayerBookEnum(prayerbook);
		var prayerIds = defaultPrayerOrder(prayerBookEnum);
		for (int prayerId : prayerIds)
		{
			var prayerObjId = prayerBookEnum.getIntValue(prayerId);
			var prayerObj = client.getItemDefinition(prayerObjId);
			var prayerWidget = client.getWidget(prayerObj.getIntValue(ParamID.OC_PRAYER_COMPONENT));

			assert prayerWidget != null;

			int widgetConfig = prayerWidget.getClickMask();
			// remove drag flag
			widgetConfig &= ~DRAG;
			// remove drag on flag
			widgetConfig &= ~DRAG_ON;
			prayerWidget.setClickMask(widgetConfig);
		}
	}
```


Patch:
diff --git a/runelite-api/src/main/java/net/runelite/api/EnumID.java b/runelite-api/src/main/java/net/runelite/api/EnumID.java
index e34eb45c9..2df707e33 100644
--- a/runelite-api/src/main/java/net/runelite/api/EnumID.java
+++ b/runelite-api/src/main/java/net/runelite/api/EnumID.java
@@ -50,6 +50,12 @@ public final class EnumID
 	 * val: namedobj
 	 */
 	public static final int PETS = 2158;
+	public static final int POH_COSTUMES_CLUE_BEGINNER = 3293;
+	public static final int POH_COSTUMES_CLUE_EASY = 3294;
+	public static final int POH_COSTUMES_CLUE_MEDIUM = 3295;
+	public static final int POH_COSTUMES_CLUE_HARD = 3296;
+	public static final int POH_COSTUMES_CLUE_ELITE = 3297;
+	public static final int POH_COSTUMES_CLUE_MASTER = 3298;
 	public static final int CLAN_RANK_NAME = 3797;
 	public static final int CLAN_RANK_GRAPHIC = 3798;
 
diff --git a/runelite-api/src/main/java/net/runelite/api/FontTypeFace.java b/runelite-api/src/main/java/net/runelite/api/FontTypeFace.java
index 59241300b..10f189e08 100644
--- a/runelite-api/src/main/java/net/runelite/api/FontTypeFace.java
+++ b/runelite-api/src/main/java/net/runelite/api/FontTypeFace.java
@@ -24,6 +24,9 @@
  */
 package net.runelite.api;
 
+import net.runelite.api.widgets.WidgetTextAlignment;
+import org.intellij.lang.annotations.MagicConstant;
+
 /**
  * A bitmap Font in Jagex's format
  */
@@ -32,4 +35,11 @@ public interface FontTypeFace
 	int getTextWidth(String text);
 
 	int getBaseline();
+
+	void drawWidgetText(
+		String text,
+		int x, int y, int width, int height,
+		int rgb, int shadowRGB, int alpha,
+		@MagicConstant(valuesFromClass = WidgetTextAlignment.class) int xTextAlignment, @MagicConstant(valuesFromClass = WidgetTextAlignment.class) int yTextAlignment,
+		int lineHeight);
 }
diff --git a/runelite-api/src/main/java/net/runelite/api/Model.java b/runelite-api/src/main/java/net/runelite/api/Model.java
index ff0e15d2c..219fca1b5 100644
--- a/runelite-api/src/main/java/net/runelite/api/Model.java
+++ b/runelite-api/src/main/java/net/runelite/api/Model.java
@@ -83,4 +83,6 @@ public interface Model extends Mesh, Renderable
 	int[] getTexIndices3();
 
 	Model getUnskewedModel();
+
+	void drawFrustum(int zero, int xRotate, int yRotate, int zRotate, int xCamera, int yCamera, int zCamera);
 }
diff --git a/runelite-api/src/main/java/net/runelite/api/Prayer.java b/runelite-api/src/main/java/net/runelite/api/Prayer.java
index 71f21e418..1aec5cc63 100644
--- a/runelite-api/src/main/java/net/runelite/api/Prayer.java
+++ b/runelite-api/src/main/java/net/runelite/api/Prayer.java
@@ -27,134 +27,230 @@ package net.runelite.api;
 import net.runelite.api.annotations.Varbit;
 
 /**
- * An enumeration of different prayer spells.
+ * An enumeration of prayers.
  */
 public enum Prayer
 {
 	/**
 	 * Thick Skin (Level 1, Defence).
 	 */
-	THICK_SKIN(Varbits.PRAYER_THICK_SKIN, 5.0),
+	THICK_SKIN(Varbits.PRAYER_THICK_SKIN),
 	/**
 	 * Burst of Strength (Level 4, Strength).
 	 */
-	BURST_OF_STRENGTH(Varbits.PRAYER_BURST_OF_STRENGTH, 5.0),
+	BURST_OF_STRENGTH(Varbits.PRAYER_BURST_OF_STRENGTH),
 	/**
 	 * Clarity of Thought (Level 7, Attack).
 	 */
-	CLARITY_OF_THOUGHT(Varbits.PRAYER_CLARITY_OF_THOUGHT, 5.0),
+	CLARITY_OF_THOUGHT(Varbits.PRAYER_CLARITY_OF_THOUGHT),
 	/**
 	 * Sharp Eye (Level 8, Ranging).
 	 */
-	SHARP_EYE(Varbits.PRAYER_SHARP_EYE, 5.0),
+	SHARP_EYE(Varbits.PRAYER_SHARP_EYE),
 	/**
 	 * Mystic Will (Level 9, Magic).
 	 */
-	MYSTIC_WILL(Varbits.PRAYER_MYSTIC_WILL, 5.0),
+	MYSTIC_WILL(Varbits.PRAYER_MYSTIC_WILL),
 	/**
 	 * Rock Skin (Level 10, Defence).
 	 */
-	ROCK_SKIN(Varbits.PRAYER_ROCK_SKIN, 10.0),
+	ROCK_SKIN(Varbits.PRAYER_ROCK_SKIN),
 	/**
 	 * Superhuman Strength (Level 13, Strength).
 	 */
-	SUPERHUMAN_STRENGTH(Varbits.PRAYER_SUPERHUMAN_STRENGTH, 10.0),
+	SUPERHUMAN_STRENGTH(Varbits.PRAYER_SUPERHUMAN_STRENGTH),
 	/**
 	 * Improved Reflexes (Level 16, Attack).
 	 */
-	IMPROVED_REFLEXES(Varbits.PRAYER_IMPROVED_REFLEXES, 10.0),
+	IMPROVED_REFLEXES(Varbits.PRAYER_IMPROVED_REFLEXES),
 	/**
 	 * Rapid Restore (Level 19, Stats).
 	 */
-	RAPID_RESTORE(Varbits.PRAYER_RAPID_RESTORE, 60.0 / 36.0),
+	RAPID_RESTORE(Varbits.PRAYER_RAPID_RESTORE),
 	/**
 	 * Rapid Heal (Level 22, Hitpoints).
 	 */
-	RAPID_HEAL(Varbits.PRAYER_RAPID_HEAL, 60.0 / 18),
+	RAPID_HEAL(Varbits.PRAYER_RAPID_HEAL),
 	/**
 	 * Protect Item (Level 25).
 	 */
-	PROTECT_ITEM(Varbits.PRAYER_PROTECT_ITEM, 60.0 / 18),
+	PROTECT_ITEM(Varbits.PRAYER_PROTECT_ITEM),
 	/**
 	 * Hawk Eye (Level 26, Ranging).
 	 */
-	HAWK_EYE(Varbits.PRAYER_HAWK_EYE, 10.0),
+	HAWK_EYE(Varbits.PRAYER_HAWK_EYE),
 	/**
 	 * Mystic Lore (Level 27, Magic).
 	 */
-	MYSTIC_LORE(Varbits.PRAYER_MYSTIC_LORE, 10.0),
+	MYSTIC_LORE(Varbits.PRAYER_MYSTIC_LORE),
 	/**
 	 * Steel Skin (Level 28, Defence).
 	 */
-	STEEL_SKIN(Varbits.PRAYER_STEEL_SKIN, 20.0),
+	STEEL_SKIN(Varbits.PRAYER_STEEL_SKIN),
 	/**
 	 * Ultimate Strength (Level 31, Strength).
 	 */
-	ULTIMATE_STRENGTH(Varbits.PRAYER_ULTIMATE_STRENGTH, 20.0),
+	ULTIMATE_STRENGTH(Varbits.PRAYER_ULTIMATE_STRENGTH),
 	/**
 	 * Incredible Reflexes (Level 34, Attack).
 	 */
-	INCREDIBLE_REFLEXES(Varbits.PRAYER_INCREDIBLE_REFLEXES, 20.0),
+	INCREDIBLE_REFLEXES(Varbits.PRAYER_INCREDIBLE_REFLEXES),
 	/**
 	 * Protect from Magic (Level 37).
 	 */
-	PROTECT_FROM_MAGIC(Varbits.PRAYER_PROTECT_FROM_MAGIC, 20.0),
+	PROTECT_FROM_MAGIC(Varbits.PRAYER_PROTECT_FROM_MAGIC),
 	/**
 	 * Protect from Missiles (Level 40).
 	 */
-	PROTECT_FROM_MISSILES(Varbits.PRAYER_PROTECT_FROM_MISSILES, 20.0),
+	PROTECT_FROM_MISSILES(Varbits.PRAYER_PROTECT_FROM_MISSILES),
 	/**
 	 * Protect from Melee (Level 43).
 	 */
-	PROTECT_FROM_MELEE(Varbits.PRAYER_PROTECT_FROM_MELEE, 20.0),
+	PROTECT_FROM_MELEE(Varbits.PRAYER_PROTECT_FROM_MELEE),
 	/**
 	 * Eagle Eye (Level 44, Ranging).
 	 */
-	EAGLE_EYE(Varbits.PRAYER_EAGLE_EYE, 20.0),
+	EAGLE_EYE(Varbits.PRAYER_EAGLE_EYE),
 	/**
 	 * Mystic Might (Level 45, Magic).
 	 */
-	MYSTIC_MIGHT(Varbits.PRAYER_MYSTIC_MIGHT, 20.0),
+	MYSTIC_MIGHT(Varbits.PRAYER_MYSTIC_MIGHT),
 	/**
 	 * Retribution (Level 46).
 	 */
-	RETRIBUTION(Varbits.PRAYER_RETRIBUTION, 5.0),
+	RETRIBUTION(Varbits.PRAYER_RETRIBUTION),
 	/**
 	 * Redemption (Level 49).
 	 */
-	REDEMPTION(Varbits.PRAYER_REDEMPTION, 10.0),
+	REDEMPTION(Varbits.PRAYER_REDEMPTION),
 	/**
 	 * Smite (Level 52).
 	 */
-	SMITE(Varbits.PRAYER_SMITE, 30.0),
+	SMITE(Varbits.PRAYER_SMITE),
 	/**
 	 * Chivalry (Level 60, Defence/Strength/Attack).
 	 */
-	CHIVALRY(Varbits.PRAYER_CHIVALRY, 40.0),
+	CHIVALRY(Varbits.PRAYER_CHIVALRY),
 	/**
 	 * Piety (Level 70, Defence/Strength/Attack).
 	 */
-	PIETY(Varbits.PRAYER_PIETY, 40.0),
+	PIETY(Varbits.PRAYER_PIETY),
 	/**
 	 * Preserve (Level 55).
 	 */
-	PRESERVE(Varbits.PRAYER_PRESERVE, 60.0 / 18),
+	PRESERVE(Varbits.PRAYER_PRESERVE),
 	/**
 	 * Rigour (Level 74, Ranging/Damage/Defence).
 	 */
-	RIGOUR(Varbits.PRAYER_RIGOUR, 40.0),
+	RIGOUR(Varbits.PRAYER_RIGOUR),
 	/**
 	 * Augury (Level 77, Magic/Magic Def./Defence).
 	 */
-	AUGURY(Varbits.PRAYER_AUGURY, 40.0);
+	AUGURY(Varbits.PRAYER_AUGURY),
+
+	/**
+	 * Ruinous Powers Rejuvenation (Level 60).
+	 */
+	RP_REJUVENATION(Varbits.PRAYER_RP_REJUVENATION),
+	/**
+	 * Ruinous Powers Ancient Strength (Level 61).
+	 */
+	RP_ANCIENT_STRENGTH(Varbits.PRAYER_RP_ANCIENT_STRENGTH),
+	/**
+	 * Ruinous Powers Ancient Sight (Level 62).
+	 */
+	RP_ANCIENT_SIGHT(Varbits.PRAYER_RP_ANCIENT_SIGHT),
+	/**
+	 * Ruinous Powers Ancient Will (Level 63).
+	 */
+	RP_ANCIENT_WILL(Varbits.PRAYER_RP_ANCIENT_WILL),
+	/**
+	 * Ruinous Powers Protect Item (Level 65).
+	 */
+	RP_PROTECT_ITEM(Varbits.PRAYER_RP_PROTECT_ITEM),
+	/**
+	 * Ruinous Powers Ruinous Grace (Level 66).
+	 */
+	RP_RUINOUS_GRACE(Varbits.PRAYER_RP_RUINOUS_GRACE),
+	/**
+	 * Ruinous Powers Dampen Magic (Level 67).
+	 */
+	RP_DAMPEN_MAGIC(Varbits.PRAYER_RP_DAMPEN_MAGIC),
+	/**
+	 * Ruinous Powers Dampen Ranged (Level 69).
+	 */
+	RP_DAMPEN_RANGED(Varbits.PRAYER_RP_DAMPEN_RANGED),
+	/**
+	 * Ruinous Powers Dampen Melee (Level 71).
+	 */
+	RP_DAMPEN_MELEE(Varbits.PRAYER_RP_DAMPEN_MELEE),
+	/**
+	 * Ruinous Powers Trinitas (Level 72).
+	 */
+	RP_TRINITAS(Varbits.PRAYER_RP_TRINITAS),
+	/**
+	 * Ruinous Powers Berserker (Level 74).
+	 */
+	RP_BERSERKER(Varbits.PRAYER_RP_BERSERKER),
+	/**
+	 * Ruinous Powers Purge (Level 75).
+	 */
+	RP_PURGE(Varbits.PRAYER_RP_PURGE),
+	/**
+	 * Ruinous Powers Metabolise (Level 77).
+	 */
+	RP_METABOLISE(Varbits.PRAYER_RP_METABOLISE),
+	/**
+	 * Ruinous Powers Rebuke (Level 78).
+	 */
+	RP_REBUKE(Varbits.PRAYER_RP_REBUKE),
+	/**
+	 * Ruinous Powers Vindication (Level 80).
+	 */
+	RP_VINDICATION(Varbits.PRAYER_RP_VINDICATION),
+	/**
+	 * Ruinous Powers Decimate (Level 82).
+	 */
+	RP_DECIMATE(Varbits.PRAYER_RP_DECIMATE),
+	/**
+	 * Ruinous Powers Annihilate (Level 84).
+	 */
+	RP_ANNIHILATE(Varbits.PRAYER_RP_ANNIHILATE),
+	/**
+	 * Ruinous Powers Vaporise (Level 86).
+	 */
+	RP_VAPORISE(Varbits.PRAYER_RP_VAPORISE),
+	/**
+	 * Ruinous Powers Fumus' Vow (Level 87).
+	 */
+	RP_FUMUS_VOW(Varbits.PRAYER_RP_FUMUS_VOW),
+	/**
+	 * Ruinous Powers Umbra's Vow (Level 88).
+	 */
+	RP_UMBRA_VOW(Varbits.PRAYER_RP_UMBRA_VOW),
+	/**
+	 * Ruinous Powers Cruor's Vow (Level 89).
+	 */
+	RP_CRUORS_VOW(Varbits.PRAYER_RP_CRUORS_VOW),
+	/**
+	 * Ruinous Powers Glacies' Vow (Level 90).
+	 */
+	RP_GLACIES_VOW(Varbits.PRAYER_RP_GLACIES_VOW),
+	/**
+	 * Ruinous Powers Wrath (Level 91).
+	 */
+	RP_WRATH(Varbits.PRAYER_RP_WRATH),
+	/**
+	 * Ruinous Powers Intensify (Level 92).
+	 */
+	RP_INTENSIFY(Varbits.PRAYER_RP_INTENSIFY),
+	;
 
 	private final int varbit;
-	private final double drainRate;
 
-	Prayer(@Varbit int varbit, double drainRate)
+	Prayer(@Varbit int varbit)
 	{
 		this.varbit = varbit;
-		this.drainRate = drainRate;
 	}
 
 	/**
@@ -167,14 +263,4 @@ public enum Prayer
 	{
 		return varbit;
 	}
-
-	/**
-	 * Gets the prayer drain rate (measured in pray points/minute)
-	 *
-	 * @return the prayer drain rate
-	 */
-	public double getDrainRate()
-	{
-		return drainRate;
-	}
 }
diff --git a/runelite-api/src/main/java/net/runelite/api/Rasterizer.java b/runelite-api/src/main/java/net/runelite/api/Rasterizer.java
index 84c3b1beb..5e29e6c14 100644
--- a/runelite-api/src/main/java/net/runelite/api/Rasterizer.java
+++ b/runelite-api/src/main/java/net/runelite/api/Rasterizer.java
@@ -70,4 +70,8 @@ public interface Rasterizer
 	 * Draws a gouraud shaded filled triangle onto the rasterizer buffer at rasterizer opacity
 	 */
 	void rasterGouraud(int y0, int y1, int y2, int x0, int x1, int x2, int hsl0, int hsl1, int hsl2);
+
+	void setDrawRegion(int x0, int y0, int x1, int x2);
+
+	void resetRasterClipping();
 }
diff --git a/runelite-api/src/main/java/net/runelite/api/SpriteID.java b/runelite-api/src/main/java/net/runelite/api/SpriteID.java
index bfb09fe2a..661676617 100644
--- a/runelite-api/src/main/java/net/runelite/api/SpriteID.java
+++ b/runelite-api/src/main/java/net/runelite/api/SpriteID.java
@@ -1683,5 +1683,29 @@ public final class SpriteID
 	public static final int HEALTHBAR_PURPLE_BACK_140PX = 4725;
 	public static final int HEALTHBAR_PURPLE_FRONT_160PX = 4726;
 	public static final int HEALTHBAR_PURPLE_BACK_160PX = 4727;
+	public static final int PRAYER_RP_ANCIENT_STRENGTH = 4843;
+	public static final int PRAYER_RP_ANCIENT_SIGHT = 4844;
+	public static final int PRAYER_RP_ANCIENT_WILL = 4845;
+	public static final int PRAYER_RP_TRINITAS = 4850;
+	public static final int PRAYER_RP_DECIMATE = 4854;
+	public static final int PRAYER_RP_ANNIHILATE = 4855;
+	public static final int PRAYER_RP_VAPORISE = 4856;
+	public static final int PRAYER_RP_DAMPEN_MELEE = 4849;
+	public static final int PRAYER_RP_DAMPEN_RANGED = 4848;
+	public static final int PRAYER_RP_DAMPEN_MAGIC = 4847;
+	public static final int PRAYER_RP_PURGE = 4852;
+	public static final int PRAYER_RP_REJUVENATION = 4842;
+	public static final int PRAYER_RP_RUINOUS_GRACE = 4846;
+	public static final int PRAYER_RP_WRATH = 4862;
+	public static final int PRAYER_RP_METABOLISE = 4853;
+	public static final int PRAYER_RP_BERSERKER = 4851;
+	public static final int PRAYER_RP_FUMUS_VOW = 4858;
+	public static final int PRAYER_RP_CRUORS_VOW = 4860;
+	public static final int PRAYER_RP_UMBRAS_VOW = 4859;
+	public static final int PRAYER_RP_GLACIES_VOW = 4861;
+	public static final int PRAYER_RP_INTENSIFY = 4864;
+	public static final int PRAYER_RP_REBUKE = 4857;
+	public static final int PRAYER_RP_VINDICATION = 4863;
+	public static final int PRAYER_RP_PROTECT_ITEM = 4865;
 	public static final int ACTIVATED_PRAYER_BACKGROUND = 4892;
 }
diff --git a/runelite-api/src/main/java/net/runelite/api/Varbits.java b/runelite-api/src/main/java/net/runelite/api/Varbits.java
index e8bf47b38..5c5e38737 100644
--- a/runelite-api/src/main/java/net/runelite/api/Varbits.java
+++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java
@@ -152,6 +152,34 @@ public final class Varbits
 	public static final int PRAYER_RIGOUR = 5464;
 	public static final int PRAYER_AUGURY = 5465;
 
+	/**
+	 * Ruinous Powers
+	 */
+	public static final int PRAYER_RP_REJUVENATION = 14840;
+	public static final int PRAYER_RP_ANCIENT_STRENGTH = 14829;
+	public static final int PRAYER_RP_ANCIENT_SIGHT = 14830;
+	public static final int PRAYER_RP_ANCIENT_WILL = 14831;
+	public static final int PRAYER_RP_PROTECT_ITEM = 14966;
+	public static final int PRAYER_RP_RUINOUS_GRACE = 14841;
+	public static final int PRAYER_RP_DAMPEN_MAGIC = 14964;
+	public static final int PRAYER_RP_DAMPEN_RANGED = 14963;
+	public static final int PRAYER_RP_DAMPEN_MELEE = 14962;
+	public static final int PRAYER_RP_TRINITAS = 14832;
+	public static final int PRAYER_RP_BERSERKER = 14844;
+	public static final int PRAYER_RP_PURGE = 14839;
+	public static final int PRAYER_RP_METABOLISE = 14843;
+	public static final int PRAYER_RP_REBUKE = 14850;
+	public static final int PRAYER_RP_VINDICATION = 14851;
+	public static final int PRAYER_RP_DECIMATE = 14833;
+	public static final int PRAYER_RP_ANNIHILATE = 14834;
+	public static final int PRAYER_RP_VAPORISE = 14835;
+	public static final int PRAYER_RP_FUMUS_VOW = 14845;
+	public static final int PRAYER_RP_UMBRA_VOW = 14847;
+	public static final int PRAYER_RP_CRUORS_VOW = 14846;
+	public static final int PRAYER_RP_GLACIES_VOW = 14848;
+	public static final int PRAYER_RP_WRATH = 14842;
+	public static final int PRAYER_RP_INTENSIFY = 14965;
+
 	/**
 	 * Diary Entries
 	 */
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FremennikDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FremennikDiaryRequirement.java
index 64ac3feb0..dfd2fde23 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FremennikDiaryRequirement.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FremennikDiaryRequirement.java
@@ -111,7 +111,7 @@ public class FremennikDiaryRequirement extends GenericDiaryRequirement
 			new QuestRequirement(Quest.THE_GIANT_DWARF, true));
 
 		// ELITE
-		add("Craft 56 astral runes from Essence simultaneously from Essence without the use of Extracts.",
+		add("Craft 56 astral runes simultaneously from Essence without the use of Extracts.",
 			new SkillRequirement(Skill.RUNECRAFT, 82),
 			new QuestRequirement(Quest.LUNAR_DIPLOMACY));
 		add("Create a dragonstone amulet in the Neitiznot furnace.",
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java
index dd9e82de8..0314a420b 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java
@@ -144,6 +144,7 @@ public class ClueScrollPlugin extends Plugin
 	private static final Color HIGHLIGHT_HOVER_BORDER_COLOR = HIGHLIGHT_BORDER_COLOR.darker();
 	private static final Color HIGHLIGHT_FILL_COLOR = new Color(0, 255, 0, 20);
 	private static final String CLUE_TAG_NAME = "clue";
+	private static final String TREASURE_CHEST_TAG_NAME = "treasure chest";
 	private static final int[] RUNEPOUCH_AMOUNT_VARBITS = {
 		Varbits.RUNE_POUCH_AMOUNT1, Varbits.RUNE_POUCH_AMOUNT2, Varbits.RUNE_POUCH_AMOUNT3, Varbits.RUNE_POUCH_AMOUNT4
 	};
@@ -251,11 +252,13 @@ public class ClueScrollPlugin extends Plugin
 		overlayManager.add(clueScrollWorldOverlay);
 		overlayManager.add(clueScrollMusicOverlay);
 		tagManager.registerTag(CLUE_TAG_NAME, this::testClueTag);
+		tagManager.registerTag(TREASURE_CHEST_TAG_NAME, this::testTreasureChestTag);
 	}
 
 	@Override
 	protected void shutDown() throws Exception
 	{
+		tagManager.unregisterTag(TREASURE_CHEST_TAG_NAME);
 		tagManager.unregisterTag(CLUE_TAG_NAME);
 		overlayManager.remove(clueScrollOverlay);
 		overlayManager.remove(clueScrollEmoteOverlay);
@@ -1233,6 +1236,29 @@ public class ClueScrollPlugin extends Plugin
 		}
 	}
 
+	private boolean testTreasureChestTag(int itemId)
+	{
+		EnumComposition[] enums = {
+			client.getEnum(EnumID.POH_COSTUMES_CLUE_BEGINNER),
+			client.getEnum(EnumID.POH_COSTUMES_CLUE_EASY),
+			client.getEnum(EnumID.POH_COSTUMES_CLUE_MEDIUM),
+			client.getEnum(EnumID.POH_COSTUMES_CLUE_HARD),
+			client.getEnum(EnumID.POH_COSTUMES_CLUE_ELITE),
+			client.getEnum(EnumID.POH_COSTUMES_CLUE_MASTER)
+		};
+		for (var e : enums)
+		{
+			for (int i : e.getIntVals())
+			{
+				if (i == itemId)
+				{
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
 	private Consumer<MenuEntry> setNoteConsumer(int key)
 	{
 		return e -> chatboxPanelManager.openTextInput("Enter note")
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java
index 8015990dd..aab58e6a3 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java
@@ -254,7 +254,7 @@ public class CoordinateClue extends ClueScroll implements LocationClueScroll
 	@Getter(AccessLevel.PRIVATE)
 	private final WorldPoint location;
 	/**
-	 * For regions which are mirrored, the location of the the clue in the mirrored region.
+	 * For regions which are mirrored, the location of the clue in the mirrored region.
 	 */
 	@Nullable
 	private final WorldPoint mirrorLocation;
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java
index 63bb59947..634f8ca2a 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java
@@ -92,27 +92,40 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, Nam
 		item(ItemID.GILDED_PICKAXE),
 		item(ItemID._3RD_AGE_PICKAXE),
 		item(ItemID.CRYSTAL_PICKAXE),
-		item(ItemID.CRYSTAL_PICKAXE_INACTIVE)
+		item(ItemID.CRYSTAL_PICKAXE_INACTIVE),
+		item(ItemID.TRAILBLAZER_PICKAXE)
 	);
 
 	private static final AnyRequirementCollection ANY_AXE = any("Any Axe",
 		item(ItemID.BRONZE_AXE),
+		item(ItemID.BRONZE_FELLING_AXE),
 		item(ItemID.IRON_AXE),
+		item(ItemID.IRON_FELLING_AXE),
 		item(ItemID.STEEL_AXE),
+		item(ItemID.STEEL_FELLING_AXE),
 		item(ItemID.BLACK_AXE),
+		item(ItemID.BLACK_FELLING_AXE),
 		item(ItemID.MITHRIL_AXE),
+		item(ItemID.MITHRIL_FELLING_AXE),
 		item(ItemID.ADAMANT_AXE),
+		item(ItemID.ADAMANT_FELLING_AXE),
 		item(ItemID.RUNE_AXE),
+		item(ItemID.RUNE_FELLING_AXE),
 		item(ItemID.DRAGON_AXE),
 		item(ItemID.DRAGON_AXE_OR),
+		item(ItemID.DRAGON_FELLING_AXE),
 		item(ItemID.INFERNAL_AXE),
 		item(ItemID.INFERNAL_AXE_OR),
 		item(ItemID.INFERNAL_AXE_UNCHARGED),
 		item(ItemID.INFERNAL_AXE_UNCHARGED_25371),
 		item(ItemID.GILDED_AXE),
 		item(ItemID._3RD_AGE_AXE),
+		item(ItemID._3RD_AGE_FELLING_AXE),
 		item(ItemID.CRYSTAL_AXE),
-		item(ItemID.CRYSTAL_AXE_INACTIVE)
+		item(ItemID.CRYSTAL_AXE_INACTIVE),
+		item(ItemID.CRYSTAL_FELLING_AXE),
+		item(ItemID.CRYSTAL_FELLING_AXE_INACTIVE),
+		item(ItemID.TRAILBLAZER_AXE)
 	);
 
 	private static final AnyRequirementCollection ANY_HARPOON = any("Harpoon",
@@ -125,7 +138,8 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, Nam
 		item(ItemID.INFERNAL_HARPOON_UNCHARGED),
 		item(ItemID.INFERNAL_HARPOON_UNCHARGED_25367),
 		item(ItemID.CRYSTAL_HARPOON),
-		item(ItemID.CRYSTAL_HARPOON_INACTIVE)
+		item(ItemID.CRYSTAL_HARPOON_INACTIVE),
+		item(ItemID.TRAILBLAZER_HARPOON)
 	);
 
 	private static final AnyRequirementCollection ANY_HAMMER = any("Hammer",
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/PrayerType.java b/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/PrayerType.java
deleted file mode 100644
index 4e7efb793..000000000
--- a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/PrayerType.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2018, Adam <Adam@sigterm.info>
- * 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.experiencedrop;
-
-enum PrayerType
-{
-	MELEE,
-	RANGE,
-	MAGIC;
-}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpPrayer.java b/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpPrayer.java
deleted file mode 100644
index 61ff0b088..000000000
--- a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpPrayer.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2018, Adam <Adam@sigterm.info>
- * 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.experiencedrop;
-
-import lombok.Getter;
-import net.runelite.api.Prayer;
-import static net.runelite.api.Prayer.*;
-import static net.runelite.client.plugins.experiencedrop.PrayerType.MAGIC;
-import static net.runelite.client.plugins.experiencedrop.PrayerType.MELEE;
-import static net.runelite.client.plugins.experiencedrop.PrayerType.RANGE;
-
-enum XpPrayer
-{
-	XP_BURST_OF_STRENGTH(BURST_OF_STRENGTH, MELEE),
-	XP_CLARITY_OF_THOUGHT(CLARITY_OF_THOUGHT, MELEE),
-	XP_SHARP_EYE(SHARP_EYE, RANGE),
-	XP_MYSTIC_WILL(MYSTIC_WILL, MAGIC),
-	XP_SUPERHUMAN_STRENGTH(SUPERHUMAN_STRENGTH, MELEE),
-	XP_IMPROVED_REFLEXES(IMPROVED_REFLEXES, MELEE),
-	XP_HAWK_EYE(HAWK_EYE, RANGE),
-	XP_MYSTIC_LORE(MYSTIC_LORE, MAGIC),
-	XP_ULTIMATE_STRENGTH(ULTIMATE_STRENGTH, MELEE),
-	XP_INCREDIBLE_REFLEXES(INCREDIBLE_REFLEXES, MELEE),
-	XP_EAGLE_EYE(EAGLE_EYE, RANGE),
-	XP_MYSTIC_MIGHT(MYSTIC_MIGHT, MAGIC),
-	XP_CHIVALRY(CHIVALRY, MELEE),
-	XP_PIETY(PIETY, MELEE),
-	XP_RIGOUR(RIGOUR, RANGE),
-	XP_AUGURY(AUGURY, MAGIC);
-
-	@Getter
-	private final Prayer prayer;
-	@Getter
-	private final PrayerType type;
-
-	XpPrayer(Prayer prayer, PrayerType type)
-	{
-		this.prayer = prayer;
-		this.type = type;
-	}
-}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java
index d2496ffa4..c32953a85 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java
@@ -305,6 +305,9 @@ public class LootTrackerPlugin extends Plugin
 	private static final String THEATRE_OF_BLOOD = "Theatre of Blood";
 	private static final String TOMBS_OF_AMASCUT = "Tombs of Amascut";
 
+	private static final int FONT_OF_CONSUMPTION_REGION = 12106;
+	private static final String FONT_OF_CONSUMPTION_USE_MESSAGE = "You place the Unsired into the Font of Consumption...";
+
 	private static final Set<Character> VOWELS = ImmutableSet.of('a', 'e', 'i', 'o', 'u');
 
 	@Inject
@@ -1099,6 +1102,11 @@ public class LootTrackerPlugin extends Plugin
 			onInvChange(collectInvItems(LootRecordType.EVENT, client.getLocalPlayer().getInteracting().getName()));
 			return;
 		}
+
+		if (regionID == FONT_OF_CONSUMPTION_REGION && message.equals(FONT_OF_CONSUMPTION_USE_MESSAGE))
+		{
+			onInvChange(collectInvItems(LootRecordType.EVENT, "Unsired"));
+		}
 	}
 
 	@Subscribe
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerPlugin.java
index a1c868a18..fb2ed7643 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerPlugin.java
@@ -34,6 +34,7 @@ import javax.annotation.Nullable;
 import javax.inject.Inject;
 import lombok.AccessLevel;
 import lombok.Getter;
+import lombok.Setter;
 import net.runelite.api.Client;
 import net.runelite.api.Constants;
 import net.runelite.api.InventoryID;
@@ -72,6 +73,7 @@ public class PrayerPlugin extends Plugin
 	private boolean prayersActive = false;
 
 	@Getter(AccessLevel.PACKAGE)
+	@Setter(AccessLevel.PACKAGE)
 	private int prayerBonus;
 
 	@Inject
@@ -352,36 +354,37 @@ public class PrayerPlugin extends Plugin
 		}
 	}
 
-	private static double getPrayerDrainRate(Client client)
+	private static int getDrainEffect(Client client)
 	{
-		double drainRate = 0.0;
+		int drainEffect = 0;
 
-		for (Prayer prayer : Prayer.values())
+		for (PrayerType prayerType : PrayerType.values())
 		{
-			if (client.isPrayerActive(prayer))
+			if (client.isPrayerActive(prayerType.getPrayer()))
 			{
-				drainRate += prayer.getDrainRate();
+				drainEffect += prayerType.getDrainEffect();
 			}
 		}
 
-		return drainRate;
+		return drainEffect;
 	}
 
 	String getEstimatedTimeRemaining(boolean formatForOrb)
 	{
-		final double drainRate = getPrayerDrainRate(client);
+		final int drainEffect = getDrainEffect(client);
 
-		if (drainRate == 0)
+		if (drainEffect == 0)
 		{
 			return "N/A";
 		}
 
-		final int currentPrayer = client.getBoostedSkillLevel(Skill.PRAYER);
-
 		// Calculate how many seconds each prayer points last so the prayer bonus can be applied
-		final double secondsPerPoint = (60.0 / drainRate) * (1.0 + (prayerBonus / 30.0));
+		// https://oldschool.runescape.wiki/w/Prayer#Prayer_drain_mechanics
+		final int drainResistance = 2 * prayerBonus + 60;
+		final double secondsPerPoint = 0.6 * ((double) drainResistance / drainEffect);
 
 		// Calculate the number of seconds left
+		final int currentPrayer = client.getBoostedSkillLevel(Skill.PRAYER);
 		final double secondsLeft = (currentPrayer * secondsPerPoint);
 
 		LocalTime timeLeft = LocalTime.ofSecondOfDay((long) secondsLeft);
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerReorder.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerReorder.java
index d2b83c1c5..87f3f36da 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerReorder.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerReorder.java
@@ -118,6 +118,7 @@ class PrayerReorder
 	{
 		reordering = false;
 		clearPrayerTabMenus();
+		clientThread.invokeLater(() -> rebuildPrayers(false));
 		clientThread.invokeLater(this::redrawPrayers);
 	}
 
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerType.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerType.java
index 7ca4524f5..5f923b162 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerType.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerType.java
@@ -33,39 +33,66 @@ import net.runelite.api.SpriteID;
 @Getter
 enum PrayerType
 {
-	THICK_SKIN("Thick Skin", Prayer.THICK_SKIN, "+5% Defence", SpriteID.PRAYER_THICK_SKIN, false),
-	BURST_OF_STRENGTH("Burst of Strength", Prayer.BURST_OF_STRENGTH, "+5% Strength", SpriteID.PRAYER_BURST_OF_STRENGTH, false),
-	CLARITY_OF_THOUGHT("Clarity of Thought", Prayer.CLARITY_OF_THOUGHT, "+5% Attack", SpriteID.PRAYER_CLARITY_OF_THOUGHT, false),
-	SHARP_EYE("Sharp Eye", Prayer.SHARP_EYE, "+5% Ranged", SpriteID.PRAYER_SHARP_EYE, false),
-	MYSTIC_WILL("Mystic Will", Prayer.MYSTIC_WILL, "+5% Magical attack and defence", SpriteID.PRAYER_MYSTIC_WILL, false),
-	ROCK_SKIN("Rock Skin", Prayer.ROCK_SKIN, "+10% Defence", SpriteID.PRAYER_ROCK_SKIN, false),
-	SUPERHUMAN_STRENGTH("Superhuman Strength", Prayer.SUPERHUMAN_STRENGTH, "+10% Strength", SpriteID.PRAYER_SUPERHUMAN_STRENGTH, false),
-	IMPROVED_REFLEXES("Improved Reflexes", Prayer.IMPROVED_REFLEXES, "+10% Attack", SpriteID.PRAYER_IMPROVED_REFLEXES, false),
-	RAPID_RESTORE("Rapid Restore", Prayer.RAPID_RESTORE, "2 x Restore rate for all skills except Hitpoints and Prayer", SpriteID.PRAYER_RAPID_RESTORE, false),
-	RAPID_HEAL("Rapid Heal", Prayer.RAPID_HEAL, "2 x Restore rate for Hitpoints", SpriteID.PRAYER_RAPID_HEAL, false),
-	PROTECT_ITEM("Protect Item", Prayer.PROTECT_ITEM, "Player keeps 1 extra item when they die", SpriteID.PRAYER_PROTECT_ITEM, false),
-	HAWK_EYE("Hawk Eye", Prayer.HAWK_EYE, "+10% Ranged", SpriteID.PRAYER_HAWK_EYE, false),
-	MYSTIC_LORE("Mystic Lore", Prayer.MYSTIC_LORE, "+10% Magical attack and defence", SpriteID.PRAYER_MYSTIC_LORE, false),
-	STEEL_SKIN("Steel Skin", Prayer.STEEL_SKIN, "+15% Defence", SpriteID.PRAYER_STEEL_SKIN, false),
-	ULTIMATE_STRENGTH("Ultimate Strength", Prayer.ULTIMATE_STRENGTH, "+15% Strength", SpriteID.PRAYER_ULTIMATE_STRENGTH, false),
-	INCREDIBLE_REFLEXES("Incredible reflexes", Prayer.INCREDIBLE_REFLEXES, "+15% Attack", SpriteID.PRAYER_INCREDIBLE_REFLEXES, false),
-	PROTECT_FROM_MAGIC("protect from magic", Prayer.PROTECT_FROM_MAGIC, "Protects against magic attacks", SpriteID.PRAYER_PROTECT_FROM_MAGIC, true),
-	PROTECT_FROM_MISSILES("Protect from missiles", Prayer.PROTECT_FROM_MISSILES, "Protects against ranged attacks", SpriteID.PRAYER_PROTECT_FROM_MISSILES, true),
-	PROTECT_FROM_MELEE("Protect from melee", Prayer.PROTECT_FROM_MELEE, "Protects against melee attacks", SpriteID.PRAYER_PROTECT_FROM_MELEE, true),
-	EAGLE_EYE("Eagle Eye", Prayer.EAGLE_EYE, "+15% Ranged", SpriteID.PRAYER_EAGLE_EYE, false),
-	MYSTIC_MIGHT("Mystic Might", Prayer.MYSTIC_MIGHT, "+15% Magical attack and defence", SpriteID.PRAYER_MYSTIC_MIGHT, false),
-	RETRIBUTION("Retribution", Prayer.RETRIBUTION, "Deals damage up to 25% of your Prayer level to nearby targets upon the user's death", SpriteID.PRAYER_RETRIBUTION, true),
-	REDEMPTION("Redemption", Prayer.REDEMPTION, "Heals the player if they fall below 10% health", SpriteID.PRAYER_REDEMPTION, true),
-	SMITE("Smite", Prayer.SMITE, "Removes 1 Prayer point from an enemy for every 4 damage inflicted on the enemy", SpriteID.PRAYER_SMITE, true),
-	PRESERVE("Preserve", Prayer.PRESERVE, "Boosted stats last 50% longer", SpriteID.PRAYER_PRESERVE, false),
-	CHIVALRY("Chivalry", Prayer.CHIVALRY, "+15% Attack, +18% Strength, +20% Defence", SpriteID.PRAYER_CHIVALRY, false),
-	PIETY("Piety", Prayer.PIETY, "+20% Attack, +23% Strength, +25% Defence", SpriteID.PRAYER_PIETY, false),
-	RIGOUR("Rigour", Prayer.RIGOUR, "+20% Ranged attack, +23% Ranged strength, +25% Defence", SpriteID.PRAYER_RIGOUR, false),
-	AUGURY("Augury", Prayer.AUGURY, "+25% Magical attack and defence, +25% Defence", SpriteID.PRAYER_AUGURY, false);
+	THICK_SKIN("Thick Skin", Prayer.THICK_SKIN, "+5% Defence", SpriteID.PRAYER_THICK_SKIN, false, 3),
+	BURST_OF_STRENGTH("Burst of Strength", Prayer.BURST_OF_STRENGTH, "+5% Strength", SpriteID.PRAYER_BURST_OF_STRENGTH, false, 3),
+	CLARITY_OF_THOUGHT("Clarity of Thought", Prayer.CLARITY_OF_THOUGHT, "+5% Attack", SpriteID.PRAYER_CLARITY_OF_THOUGHT, false, 3),
+	SHARP_EYE("Sharp Eye", Prayer.SHARP_EYE, "+5% Ranged", SpriteID.PRAYER_SHARP_EYE, false, 3),
+	MYSTIC_WILL("Mystic Will", Prayer.MYSTIC_WILL, "+5% Magical attack and defence", SpriteID.PRAYER_MYSTIC_WILL, false, 3),
+	ROCK_SKIN("Rock Skin", Prayer.ROCK_SKIN, "+10% Defence", SpriteID.PRAYER_ROCK_SKIN, false, 6),
+	SUPERHUMAN_STRENGTH("Superhuman Strength", Prayer.SUPERHUMAN_STRENGTH, "+10% Strength", SpriteID.PRAYER_SUPERHUMAN_STRENGTH, false, 6),
+	IMPROVED_REFLEXES("Improved Reflexes", Prayer.IMPROVED_REFLEXES, "+10% Attack", SpriteID.PRAYER_IMPROVED_REFLEXES, false, 6),
+	RAPID_RESTORE("Rapid Restore", Prayer.RAPID_RESTORE, "2 x Restore rate for all skills except Hitpoints and Prayer", SpriteID.PRAYER_RAPID_RESTORE, false, 1),
+	RAPID_HEAL("Rapid Heal", Prayer.RAPID_HEAL, "2 x Restore rate for Hitpoints", SpriteID.PRAYER_RAPID_HEAL, false, 2),
+	PROTECT_ITEM("Protect Item", Prayer.PROTECT_ITEM, "Player keeps 1 extra item when they die", SpriteID.PRAYER_PROTECT_ITEM, false, 2),
+	HAWK_EYE("Hawk Eye", Prayer.HAWK_EYE, "+10% Ranged", SpriteID.PRAYER_HAWK_EYE, false, 6),
+	MYSTIC_LORE("Mystic Lore", Prayer.MYSTIC_LORE, "+10% Magical attack and defence", SpriteID.PRAYER_MYSTIC_LORE, false, 6),
+	STEEL_SKIN("Steel Skin", Prayer.STEEL_SKIN, "+15% Defence", SpriteID.PRAYER_STEEL_SKIN, false, 12),
+	ULTIMATE_STRENGTH("Ultimate Strength", Prayer.ULTIMATE_STRENGTH, "+15% Strength", SpriteID.PRAYER_ULTIMATE_STRENGTH, false, 12),
+	INCREDIBLE_REFLEXES("Incredible reflexes", Prayer.INCREDIBLE_REFLEXES, "+15% Attack", SpriteID.PRAYER_INCREDIBLE_REFLEXES, false, 12),
+	PROTECT_FROM_MAGIC("protect from magic", Prayer.PROTECT_FROM_MAGIC, "Protects against magic attacks", SpriteID.PRAYER_PROTECT_FROM_MAGIC, true, 12),
+	PROTECT_FROM_MISSILES("Protect from missiles", Prayer.PROTECT_FROM_MISSILES, "Protects against ranged attacks", SpriteID.PRAYER_PROTECT_FROM_MISSILES, true, 12),
+	PROTECT_FROM_MELEE("Protect from melee", Prayer.PROTECT_FROM_MELEE, "Protects against melee attacks", SpriteID.PRAYER_PROTECT_FROM_MELEE, true, 12),
+	EAGLE_EYE("Eagle Eye", Prayer.EAGLE_EYE, "+15% Ranged", SpriteID.PRAYER_EAGLE_EYE, false, 12),
+	MYSTIC_MIGHT("Mystic Might", Prayer.MYSTIC_MIGHT, "+15% Magical attack and defence", SpriteID.PRAYER_MYSTIC_MIGHT, false, 12),
+	RETRIBUTION("Retribution", Prayer.RETRIBUTION, "Deals damage up to 25% of your Prayer level to nearby targets upon the user's death", SpriteID.PRAYER_RETRIBUTION, true, 3),
+	REDEMPTION("Redemption", Prayer.REDEMPTION, "Heals the player if they fall below 10% health", SpriteID.PRAYER_REDEMPTION, true, 6),
+	SMITE("Smite", Prayer.SMITE, "Removes 1 Prayer point from an enemy for every 4 damage inflicted on the enemy", SpriteID.PRAYER_SMITE, true, 18),
+	PRESERVE("Preserve", Prayer.PRESERVE, "Boosted stats last 50% longer", SpriteID.PRAYER_PRESERVE, false, 2),
+	CHIVALRY("Chivalry", Prayer.CHIVALRY, "+15% Attack, +18% Strength, +20% Defence", SpriteID.PRAYER_CHIVALRY, false, 24),
+	PIETY("Piety", Prayer.PIETY, "+20% Attack, +23% Strength, +25% Defence", SpriteID.PRAYER_PIETY, false, 24),
+	RIGOUR("Rigour", Prayer.RIGOUR, "+20% Ranged attack, +23% Ranged strength, +25% Defence", SpriteID.PRAYER_RIGOUR, false, 24),
+	AUGURY("Augury", Prayer.AUGURY, "+25% Magical attack and defence, +25% Defence", SpriteID.PRAYER_AUGURY, false, 24),
+
+	RP_REJUVENATION("Rejuvenation", Prayer.RP_REJUVENATION, "3x Restore rate for Hitpoints", SpriteID.PRAYER_RP_REJUVENATION, false, 4),
+	RP_ANCIENT_STRENGTH("Ancient Strength", Prayer.RP_ANCIENT_STRENGTH, "+20% Attack and Strength", SpriteID.PRAYER_RP_ANCIENT_STRENGTH, false, 18),
+	RP_ANCIENT_SIGHT("Ancient Sight", Prayer.RP_ANCIENT_SIGHT, "+20% Ranged Attack & Strength", SpriteID.PRAYER_RP_ANCIENT_SIGHT, false, 18),
+	RP_ANCIENT_WILL("Ancient Will", Prayer.RP_ANCIENT_WILL, "+20% Magic Attack", SpriteID.PRAYER_RP_ANCIENT_WILL, false, 18),
+	RP_PROTECT_ITEM("Protect Item", Prayer.RP_PROTECT_ITEM, "Keep one extra item upon death", SpriteID.PRAYER_RP_PROTECT_ITEM, false, 18),
+	RP_RUINOUS_GRACE("Ruinous Grace", Prayer.RP_RUINOUS_GRACE, "Prayer points are drained in place of run energy whilst running", SpriteID.PRAYER_RP_RUINOUS_GRACE, false, 1),
+	RP_DAMPEN_MAGIC("Dampen Magic", Prayer.RP_DAMPEN_MAGIC, "100% protection from magic attacks (40% in PvP), but increases damage taken by 10%", SpriteID.PRAYER_RP_DAMPEN_MAGIC, true, 14),
+	RP_DAMPEN_RANGE("Dampen Ranged", Prayer.RP_DAMPEN_RANGED, "100% protection from ranged attacks (40% in PvP), but increases damage taken by 10%", SpriteID.PRAYER_RP_DAMPEN_RANGED, true, 14),
+	RP_DAMPEN_MELEE("Dampen Melee", Prayer.RP_DAMPEN_MELEE, "100% protection from melee attacks (40% in PvP), but increases damage taken by 10%", SpriteID.PRAYER_RP_DAMPEN_MELEE, true, 14),
+	RP_TRINITAS("Trinitas", Prayer.RP_TRINITAS, "+15% Melee Attack and Strength, +15% Ranged Attack and Strength, and +15% Magic Attack", SpriteID.PRAYER_RP_TRINITAS, false, 22),
+	RP_BERSERKER("Berserker", Prayer.RP_BERSERKER, "Boosted combat stats last 50% longer", SpriteID.PRAYER_RP_BERSERKER, false, 2),
+	RP_PURGE("Purge", Prayer.RP_PURGE, "Reduces the player's and opponent's prayer points by 33% of damage dealt", SpriteID.PRAYER_RP_PURGE, true, 18),
+	RP_METABOLISE("Metabolise", Prayer.RP_METABOLISE, "25 ticks (15 seconds) after activation, allows players to attack 1 tick earlier after eating a piece of food", SpriteID.PRAYER_RP_METABOLISE, false, 12),
+	RP_REBUKE("Rebuke", Prayer.RP_REBUKE, "Increases recoil damage by 50%", SpriteID.PRAYER_RP_REBUKE, true, 12),
+	RP_VINDICATION("Vindication", Prayer.RP_VINDICATION, "Heals the player by 25% of their base Prayer level if they fall below 10% health, draining their prayer points fully", SpriteID.PRAYER_RP_VINDICATION, true, 9),
+	RP_DECIMATE("Decimate", Prayer.RP_DECIMATE, "+25% Attack, +27% Strength", SpriteID.PRAYER_RP_DECIMATE, false, 28),
+	RP_ANNIHILATE("Annihilate", Prayer.RP_ANNIHILATE, "+25% Ranged Attack, +27% Ranged Strength", SpriteID.PRAYER_RP_ANNIHILATE, false, 28),
+	RP_VAPORISE("Vaporise", Prayer.RP_VAPORISE, "+25% Magic Attack, +4% Magic Damage", SpriteID.PRAYER_RP_VAPORISE, false, 28),
+	RP_FUMUS_VOW("Fumus' Vow", Prayer.RP_FUMUS_VOW, "Attacks that inflict poison will deal poison damage instantly", SpriteID.PRAYER_RP_FUMUS_VOW, false, 14),
+	RP_UMBRAS_VOW("Umbra's Vow", Prayer.RP_UMBRA_VOW, "Attacks drain 5% of the opponent's Defence, up to 15% of their base level", SpriteID.PRAYER_RP_UMBRAS_VOW, false, 14),
+	RP_CRUORS_VOW("Cruor's Vow", Prayer.RP_CRUORS_VOW, "Heals 3 Hitpoints and drains 3 Prayer points upon killing a target", SpriteID.PRAYER_RP_CRUORS_VOW, false, 14),
+	RP_GLACIES_VOW("Glacies' Vow", Prayer.RP_GLACIES_VOW, "Attacks drain 5% of the opponent's Magic, up to 15% of their base level", SpriteID.PRAYER_RP_GLACIES_VOW, false, 14),
+	RP_WRATH("Wrath", Prayer.RP_WRATH, "Upon death, deals damage up to 25% of the player's base Prayer level to targets in a 5x5 radius", SpriteID.PRAYER_RP_WRATH, false, 3),
+	RP_INTENSIFY("Intensify", Prayer.RP_INTENSIFY, "+40% accuracy in all attack styles", SpriteID.PRAYER_RP_INTENSIFY, false, 28),
+	;
 
 	private final String name;
 	private final Prayer prayer;
 	private final String description;
 	private final int spriteID;
 	private final boolean overhead;
+	private final int drainEffect;
 }
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/xpdrop/XpDropConfig.java
similarity index 98%
rename from runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropConfig.java
rename to runelite-client/src/main/java/net/runelite/client/plugins/xpdrop/XpDropConfig.java
index b3aaf7bc4..0d9acef95 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/xpdrop/XpDropConfig.java
@@ -22,7 +22,7 @@
  * (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.experiencedrop;
+package net.runelite.client.plugins.xpdrop;
 
 import java.awt.Color;
 import net.runelite.client.config.Config;
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/xpdrop/XpDropPlugin.java
similarity index 63%
rename from runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropPlugin.java
rename to runelite-client/src/main/java/net/runelite/client/plugins/xpdrop/XpDropPlugin.java
index 746019990..40c797612 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/experiencedrop/XpDropPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/xpdrop/XpDropPlugin.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018, Cameron <https://github.com/noremac201>, SoyChai <https://github.com/SoyChai>
+ * Copyright (c) 2023, Adam <Adam@sigterm.info>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -22,19 +23,25 @@
  * (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.experiencedrop;
+package net.runelite.client.plugins.xpdrop;
 
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.Multimap;
 import com.google.inject.Provides;
 import java.awt.Color;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.EnumMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.stream.IntStream;
+import java.util.stream.Collectors;
 import javax.inject.Inject;
 import net.runelite.api.Client;
 import net.runelite.api.EnumComposition;
 import net.runelite.api.EnumID;
+import net.runelite.api.Prayer;
 import static net.runelite.api.ScriptID.XPDROPS_SETDROPSIZE;
 import static net.runelite.api.ScriptID.XPDROP_DISABLED;
 import net.runelite.api.Skill;
@@ -56,6 +63,41 @@ import net.runelite.client.plugins.PluginDescriptor;
 )
 public class XpDropPlugin extends Plugin
 {
+	enum PrayerType
+	{
+		MELEE,
+		RANGE,
+		MAGIC;
+	}
+
+	private static final Multimap<Prayer, PrayerType> PRAYER_TYPE = new ImmutableMultimap.Builder<Prayer, PrayerType>()
+		.put(Prayer.BURST_OF_STRENGTH, PrayerType.MELEE)
+		.put(Prayer.CLARITY_OF_THOUGHT, PrayerType.MELEE)
+		.put(Prayer.SHARP_EYE, PrayerType.RANGE)
+		.put(Prayer.MYSTIC_WILL, PrayerType.MAGIC)
+		.put(Prayer.SUPERHUMAN_STRENGTH, PrayerType.MELEE)
+		.put(Prayer.IMPROVED_REFLEXES, PrayerType.MELEE)
+		.put(Prayer.HAWK_EYE, PrayerType.RANGE)
+		.put(Prayer.MYSTIC_LORE, PrayerType.MAGIC)
+		.put(Prayer.ULTIMATE_STRENGTH, PrayerType.MELEE)
+		.put(Prayer.INCREDIBLE_REFLEXES, PrayerType.MELEE)
+		.put(Prayer.EAGLE_EYE, PrayerType.RANGE)
+		.put(Prayer.MYSTIC_MIGHT, PrayerType.MAGIC)
+		.put(Prayer.CHIVALRY, PrayerType.MELEE)
+		.put(Prayer.PIETY, PrayerType.MELEE)
+		.put(Prayer.RIGOUR, PrayerType.RANGE)
+		.put(Prayer.AUGURY, PrayerType.MAGIC)
+		// RP
+		.put(Prayer.RP_ANCIENT_STRENGTH, PrayerType.MELEE)
+		.put(Prayer.RP_ANCIENT_SIGHT, PrayerType.RANGE)
+		.put(Prayer.RP_ANCIENT_WILL, PrayerType.MAGIC)
+		.putAll(Prayer.RP_TRINITAS, PrayerType.MELEE, PrayerType.RANGE, PrayerType.MAGIC)
+		.put(Prayer.RP_DECIMATE, PrayerType.MELEE)
+		.put(Prayer.RP_ANNIHILATE, PrayerType.RANGE)
+		.put(Prayer.RP_VAPORISE, PrayerType.MAGIC)
+		.putAll(Prayer.RP_INTENSIFY, PrayerType.MELEE, PrayerType.RANGE, PrayerType.MAGIC)
+		.build();
+
 	@Inject
 	private Client client;
 
@@ -65,7 +107,7 @@ public class XpDropPlugin extends Plugin
 	private int tickCounter = 0;
 	private int previousExpGained;
 	private boolean hasDropped = false;
-	private boolean correctPrayer;
+	private int xpdropColor;
 	private Skill lastSkill = null;
 	private final Map<Skill, Integer> previousSkillExpTable = new EnumMap<>(Skill.class);
 
@@ -96,51 +138,64 @@ public class XpDropPlugin extends Plugin
 		// child 0 is the xpdrop text, everything else are sprite ids for skills
 		final Widget text = children[0];
 
-		PrayerType prayer = getActivePrayerType();
-		if (prayer == null)
+		Collection<PrayerType> prayers = getActivePrayerType();
+		if (prayers.isEmpty())
 		{
 			hideSkillIcons(xpdrop);
 			resetTextColor(text);
 			return;
 		}
 
-		final IntStream spriteIDs =
+		final List<PrayerType> xpDropTypes =
 			Arrays.stream(children)
 				.skip(1) // skip text
 				.filter(Objects::nonNull)
-				.mapToInt(Widget::getSpriteId);
-
-		int color = 0;
+				.map(Widget::getSpriteId)
+				.map(id ->
+				{
+					if (id == SpriteID.SKILL_ATTACK || id == SpriteID.SKILL_STRENGTH || id == SpriteID.SKILL_DEFENCE)
+					{
+						return PrayerType.MELEE;
+					}
+					if (id == SpriteID.SKILL_RANGED)
+					{
+						return PrayerType.RANGE;
+					}
+					if (id == SpriteID.SKILL_MAGIC)
+					{
+						return PrayerType.MAGIC;
+					}
+					return null;
+				})
+				.filter(Objects::nonNull)
+				.distinct()
+				.collect(Collectors.toList());
 
-		switch (prayer)
+		if (xpDropTypes.contains(PrayerType.MELEE))
 		{
-			case MELEE:
-				if (correctPrayer || spriteIDs.anyMatch(id ->
-					id == SpriteID.SKILL_ATTACK || id == SpriteID.SKILL_STRENGTH || id == SpriteID.SKILL_DEFENCE))
-				{
-					color = config.getMeleePrayerColor().getRGB();
-					correctPrayer = true;
-				}
-				break;
-			case RANGE:
-				if (correctPrayer || spriteIDs.anyMatch(id -> id == SpriteID.SKILL_RANGED))
-				{
-					color = config.getRangePrayerColor().getRGB();
-					correctPrayer = true;
-				}
-				break;
-			case MAGIC:
-				if (correctPrayer || spriteIDs.anyMatch(id -> id == SpriteID.SKILL_MAGIC))
-				{
-					color = config.getMagePrayerColor().getRGB();
-					correctPrayer = true;
-				}
-				break;
+			if (prayers.contains(PrayerType.MELEE))
+			{
+				xpdropColor = config.getMeleePrayerColor().getRGB();
+			}
+		}
+		else if (xpDropTypes.contains(PrayerType.RANGE))
+		{
+			if (prayers.contains(PrayerType.RANGE))
+			{
+				xpdropColor = config.getRangePrayerColor().getRGB();
+			}
+		}
+		else if (xpDropTypes.contains(PrayerType.MAGIC))
+		{
+			if (prayers.contains(PrayerType.MAGIC))
+			{
+				xpdropColor = config.getMagePrayerColor().getRGB();
+			}
 		}
 
-		if (color != 0)
+		if (xpdropColor != 0)
 		{
-			text.setTextColor(color);
+			text.setTextColor(xpdropColor);
 		}
 		else
 		{
@@ -177,22 +232,22 @@ public class XpDropPlugin extends Plugin
 		}
 	}
 
-	private PrayerType getActivePrayerType()
+	private Collection<PrayerType> getActivePrayerType()
 	{
-		for (XpPrayer prayer : XpPrayer.values())
+		for (Prayer prayer : PRAYER_TYPE.keySet())
 		{
-			if (client.getServerVarbitValue(prayer.getPrayer().getVarbit()) == 1)
+			if (client.getServerVarbitValue(prayer.getVarbit()) == 1)
 			{
-				return prayer.getType();
+				return PRAYER_TYPE.get(prayer);
 			}
 		}
-		return null;
+		return Collections.emptyList();
 	}
 
 	@Subscribe
 	public void onGameTick(GameTick tick)
 	{
-		correctPrayer = false;
+		xpdropColor = 0;
 
 		final int fakeTickDelay = config.fakeXpDropDelay();
 
diff --git a/runelite-client/src/main/java/net/runelite/client/rs/RSAppletStub.java b/runelite-client/src/main/java/net/runelite/client/rs/RSAppletStub.java
index 36024b489..c061e6e1a 100644
--- a/runelite-client/src/main/java/net/runelite/client/rs/RSAppletStub.java
+++ b/runelite-client/src/main/java/net/runelite/client/rs/RSAppletStub.java
@@ -41,6 +41,7 @@ import lombok.RequiredArgsConstructor;
 import net.runelite.client.RuntimeConfig;
 import net.runelite.client.RuntimeConfigLoader;
 import net.runelite.client.ui.FatalErrorDialog;
+import net.runelite.client.util.LinkBrowser;
 
 @RequiredArgsConstructor
 class RSAppletStub implements AppletStub
@@ -129,11 +130,24 @@ class RSAppletStub implements AppletStub
 						.replace("/", "")
 						.replace(".ws", "");
 
-					SwingUtilities.invokeLater(() ->
-						new FatalErrorDialog("OldSchool RuneScape has crashed with the message: " + code + "")
-							.setTitle("RuneLite", "OldSchool RuneScape has crashed")
-							.addHelpButtons()
-							.open());
+					if (code.equals("error_game_js5connect"))
+					{
+						SwingUtilities.invokeLater(() ->
+							new FatalErrorDialog("RuneLite is unable to connect to the RuneScape update server. " +
+								"RuneScape might be offline for an update, check the game status page. If the game " +
+								"is online, then either a firewall is blocking RuneLite, or you don't have internet access.")
+								.setTitle("RuneLite", "Unable to connect to update server")
+								.addButton("Game Status", () -> LinkBrowser.browse("https://secure.runescape.com/m=news/game-status-information-centre?oldschool=1"))
+								.open());
+					}
+					else
+					{
+						SwingUtilities.invokeLater(() ->
+							new FatalErrorDialog("OldSchool RuneScape has crashed with the message: " + code + "")
+								.setTitle("RuneLite", "OldSchool RuneScape has crashed")
+								.addHelpButtons()
+								.open());
+					}
 				}
 			}
 


Test patch:
diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/prayer/PrayerPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/prayer/PrayerPluginTest.java
index 93c779f3a..bd0bf91e4 100644
--- a/runelite-client/src/test/java/net/runelite/client/plugins/prayer/PrayerPluginTest.java
+++ b/runelite-client/src/test/java/net/runelite/client/plugins/prayer/PrayerPluginTest.java
@@ -51,6 +51,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import org.mockito.Mock;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.when;
 import org.mockito.junit.MockitoJUnitRunner;
 
@@ -157,4 +158,49 @@ public class PrayerPluginTest
 
 		assertEquals("79m", prayerPlugin.getEstimatedTimeRemaining(true));
 	}
+
+	@Test
+	public void testTimeRemaining()
+	{
+		prayerPlugin.setPrayerBonus(42);
+
+		assertTime(PrayerType.THICK_SKIN, "47:31");
+		assertTime(PrayerType.BURST_OF_STRENGTH, "47:31");
+		assertTime(PrayerType.CLARITY_OF_THOUGHT, "47:31");
+		assertTime(PrayerType.SHARP_EYE, "47:31");
+		assertTime(PrayerType.MYSTIC_WILL, "47:31");
+		assertTime(PrayerType.ROCK_SKIN, "23:45");
+		assertTime(PrayerType.SUPERHUMAN_STRENGTH, "23:45");
+		assertTime(PrayerType.IMPROVED_REFLEXES, "23:45");
+		assertTime(PrayerType.RAPID_RESTORE, "2:22:33");
+		assertTime(PrayerType.RAPID_HEAL, "1:11:16");
+		assertTime(PrayerType.PROTECT_ITEM, "1:11:16");
+		assertTime(PrayerType.HAWK_EYE, "23:45");
+		assertTime(PrayerType.MYSTIC_LORE, "23:45");
+		assertTime(PrayerType.STEEL_SKIN, "11:52");
+		assertTime(PrayerType.ULTIMATE_STRENGTH, "11:52");
+		assertTime(PrayerType.INCREDIBLE_REFLEXES, "11:52");
+		assertTime(PrayerType.PROTECT_FROM_MAGIC, "11:52");
+		assertTime(PrayerType.PROTECT_FROM_MISSILES, "11:52");
+		assertTime(PrayerType.PROTECT_FROM_MELEE, "11:52");
+		assertTime(PrayerType.EAGLE_EYE, "11:52");
+		assertTime(PrayerType.MYSTIC_MIGHT, "11:52");
+		assertTime(PrayerType.RETRIBUTION, "47:31");
+		assertTime(PrayerType.REDEMPTION, "23:45");
+		assertTime(PrayerType.SMITE, "7:55");
+		assertTime(PrayerType.PRESERVE, "1:11:16");
+		assertTime(PrayerType.CHIVALRY, "5:56");
+		assertTime(PrayerType.PIETY, "5:56");
+		assertTime(PrayerType.RIGOUR, "5:56");
+		assertTime(PrayerType.AUGURY, "5:56");
+	}
+
+	private void assertTime(PrayerType prayer, String time)
+	{
+		reset(client);
+		when(client.getBoostedSkillLevel(Skill.PRAYER)).thenReturn(99);
+		when(client.isPrayerActive(prayer.getPrayer())).thenReturn(true);
+		var est = prayerPlugin.getEstimatedTimeRemaining(false);
+		assertEquals(time, est);
+	}
 }