From e94317dbb4044f5b1f9076b8f315df64f20f5730 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Apr 2026 17:14:02 +0200 Subject: [PATCH 1/2] add feature --- README.md | 7 +- build.gradle | 12 +- .../io/hydrox/quickprayerpreview/Prayer.java | 112 ++++++++++++------ .../QuickPrayerPreviewConfig.java | 55 +++++++++ .../QuickPrayerPreviewOverlay.java | 4 +- .../QuickPrayerPreviewPlugin.java | 77 ++++++++++-- .../QuickPrayerPreviewPrayerTabOverlay.java | 106 +++++++++++++++++ 7 files changed, 325 insertions(+), 48 deletions(-) create mode 100644 src/main/java/io/hydrox/quickprayerpreview/QuickPrayerPreviewConfig.java create mode 100644 src/main/java/io/hydrox/quickprayerpreview/QuickPrayerPreviewPrayerTabOverlay.java diff --git a/README.md b/README.md index 32dd7b7..9c78f3a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,7 @@ # Quick Prayer Preview -Have a glance at what quick prayers you have selected without having to edit them or turn them on. \ No newline at end of file +Have a glance at what quick prayers you have selected without having to edit them or turn them on. + +#### Orb tooltip +![img1](https://i.imgur.com/oFnpjZC.png) +#### Tab preview +![img2](https://i.imgur.com/fSARj4v.png) \ No newline at end of file diff --git a/build.gradle b/build.gradle index 767ccef..06733ee 100644 --- a/build.gradle +++ b/build.gradle @@ -18,10 +18,14 @@ dependencies { compileOnly 'org.projectlombok:lombok:1.18.4' annotationProcessor 'org.projectlombok:lombok:1.18.4' - testImplementation 'junit:junit:4.12' - testImplementation 'org.slf4j:slf4j-simple:1.7.12' - testImplementation group: 'net.runelite', name:'client', version: runeLiteVersion, { - exclude group: 'ch.qos.logback', module: 'logback-classic' + def junitVersion = "5.5.2" // max version before junit-bom was added to pom files, due to runelite restrictions + testImplementation group: "org.junit.jupiter", name: "junit-jupiter-api", version: junitVersion + testImplementation group: "org.junit.jupiter", name: "junit-jupiter-params", version: junitVersion + testImplementation group: "org.junit.jupiter", name: "junit-jupiter-engine", version: junitVersion + testImplementation group: 'net.runelite', name:'client', version: runeLiteVersion + testImplementation group: 'net.runelite', name:'jshell', version: runeLiteVersion + testImplementation(group: 'com.google.inject.extensions', name:'guice-testlib', version: "4.1.0") { + exclude group: 'com.google.inject', module: 'guice' // already provided by runelite } } diff --git a/src/main/java/io/hydrox/quickprayerpreview/Prayer.java b/src/main/java/io/hydrox/quickprayerpreview/Prayer.java index 296a8e7..a34643b 100644 --- a/src/main/java/io/hydrox/quickprayerpreview/Prayer.java +++ b/src/main/java/io/hydrox/quickprayerpreview/Prayer.java @@ -26,7 +26,11 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; -import net.runelite.api.SpriteID; +import net.runelite.api.Client; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.gameval.VarbitID; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -36,41 +40,73 @@ @RequiredArgsConstructor enum Prayer { - THICK_SKIN(0, "Thick Skin", SpriteID.PRAYER_THICK_SKIN), - BURST_OF_STRENGTH(1, "Burst of Strength", SpriteID.PRAYER_BURST_OF_STRENGTH), - CLARITY_OF_THOUGHT(2, "Clarity of Thought", SpriteID.PRAYER_CLARITY_OF_THOUGHT), - SHARP_EYE(18, "Sharp Eye", SpriteID.PRAYER_SHARP_EYE), - MYSTIC_WILL(19, "Mystic Will", SpriteID.PRAYER_MYSTIC_WILL), - ROCK_SKIN(3, "Rock Skin", SpriteID.PRAYER_ROCK_SKIN), - SUPERHUMAN_STRENGTH(4, "Superhuman Strength", SpriteID.PRAYER_SUPERHUMAN_STRENGTH), - IMPROVED_REFLEXES(5, "Improved Reflexes", SpriteID.PRAYER_IMPROVED_REFLEXES), - RAPID_RESTORE(6, "Rapid Restore", SpriteID.PRAYER_RAPID_RESTORE), - RAPID_HEAL(7, "Rapid Heal", SpriteID.PRAYER_RAPID_HEAL), - PROTECT_ITEM(8, "Protect Item", SpriteID.PRAYER_PROTECT_ITEM), - HAWK_EYE(20, "Hawk Eye", SpriteID.PRAYER_HAWK_EYE), - MYSTIC_LORE(21, "Mystic Lore", SpriteID.PRAYER_MYSTIC_LORE), - STEEL_SKIN(9, "Steel Skin", SpriteID.PRAYER_STEEL_SKIN), - ULTIMATE_STRENGTH(10, "Ultimate Strength", SpriteID.PRAYER_ULTIMATE_STRENGTH), - INCREDIBLE_REFLEXES(11, "Incredible reflexes", SpriteID.PRAYER_INCREDIBLE_REFLEXES), - PROTECT_FROM_MAGIC(12, "protect from magic", SpriteID.PRAYER_PROTECT_FROM_MAGIC), - PROTECT_FROM_MISSILES(13, "Protect from missiles", SpriteID.PRAYER_PROTECT_FROM_MISSILES), - PROTECT_FROM_MELEE(14, "Protect from melee", SpriteID.PRAYER_PROTECT_FROM_MELEE), - EAGLE_EYE(22, "Eagle Eye", SpriteID.PRAYER_EAGLE_EYE), - MYSTIC_MIGHT(23, "Mystic Might", SpriteID.PRAYER_MYSTIC_MIGHT), - RETRIBUTION(15, "Retribution", SpriteID.PRAYER_RETRIBUTION), - REDEMPTION(16, "Redemption", SpriteID.PRAYER_REDEMPTION), - SMITE(17, "Smite", SpriteID.PRAYER_SMITE), - PRESERVE(28, "Preserve", SpriteID.PRAYER_PRESERVE), - CHIVALRY(25, "Chivalry", SpriteID.PRAYER_CHIVALRY), - PIETY(26, "Piety", SpriteID.PRAYER_PIETY), - RIGOUR(24, "Rigour", SpriteID.PRAYER_RIGOUR), - AUGURY(27, "Augury", SpriteID.PRAYER_AUGURY); + THICK_SKIN(0, "Thick Skin", SpriteID.Prayeron.THICK_SKIN, InterfaceID.Prayerbook.PRAYER1), + BURST_OF_STRENGTH(1, "Burst of Strength", SpriteID.Prayeron.BURST_OF_STRENGTH, InterfaceID.Prayerbook.PRAYER2), + CLARITY_OF_THOUGHT(2, "Clarity of Thought", SpriteID.Prayeron.CLARITY_OF_THOUGHT, InterfaceID.Prayerbook.PRAYER3), + SHARP_EYE(18, "Sharp Eye", SpriteID.Prayeron.SHARP_EYE, InterfaceID.Prayerbook.PRAYER19), + MYSTIC_WILL(19, "Mystic Will", SpriteID.Prayeron.MYSTIC_WILL, InterfaceID.Prayerbook.PRAYER20), + ROCK_SKIN(3, "Rock Skin", SpriteID.Prayeron.ROCK_SKIN, InterfaceID.Prayerbook.PRAYER4), + SUPERHUMAN_STRENGTH(4, "Superhuman Strength", SpriteID.Prayeron.SUPERHUMAN_STRENGTH, InterfaceID.Prayerbook.PRAYER5), + IMPROVED_REFLEXES(5, "Improved Reflexes", SpriteID.Prayeron.IMPROVED_REFLEXES, InterfaceID.Prayerbook.PRAYER6), + RAPID_RESTORE(6, "Rapid Restore", SpriteID.Prayeron.RAPID_RESTORE, InterfaceID.Prayerbook.PRAYER7), + RAPID_HEAL(7, "Rapid Heal", SpriteID.Prayeron.RAPID_HEAL, InterfaceID.Prayerbook.PRAYER8), + PROTECT_ITEM(8, "Protect Item", SpriteID.Prayeron.PROTECT_ITEM, InterfaceID.Prayerbook.PRAYER9), + HAWK_EYE(20, "Hawk Eye", SpriteID.Prayeron.HAWK_EYE, InterfaceID.Prayerbook.PRAYER21), + MYSTIC_LORE(21, "Mystic Lore", SpriteID.Prayeron.MYSTIC_LORE, InterfaceID.Prayerbook.PRAYER22), + STEEL_SKIN(9, "Steel Skin", SpriteID.Prayeron.STEEL_SKIN, InterfaceID.Prayerbook.PRAYER10), + ULTIMATE_STRENGTH(10, "Ultimate Strength", SpriteID.Prayeron.ULTIMATE_STRENGTH, InterfaceID.Prayerbook.PRAYER11), + INCREDIBLE_REFLEXES(11, "Incredible reflexes", SpriteID.Prayeron.INCREDIBLE_REFLEXES, InterfaceID.Prayerbook.PRAYER12), + PROTECT_FROM_MAGIC(12, "protect from magic", SpriteID.Prayeron.PROTECT_FROM_MAGIC, InterfaceID.Prayerbook.PRAYER13), + PROTECT_FROM_MISSILES(13, "Protect from missiles", SpriteID.Prayeron.PROTECT_FROM_MISSILES, InterfaceID.Prayerbook.PRAYER14), + PROTECT_FROM_MELEE(14, "Protect from melee", SpriteID.Prayeron.PROTECT_FROM_MELEE, InterfaceID.Prayerbook.PRAYER15), + EAGLE_EYE(22, "Eagle Eye", SpriteID.Prayeron.EAGLE_EYE, InterfaceID.Prayerbook.PRAYER23) + { + @Override + public int getUnlockVarbit() + { + return VarbitID.PRAYER_DEADEYE_UNLOCKED; + } + + @Override + public Prayer getUnlockPrayer() + { + return DEADEYE; + } + }, + DEADEYE(-22, "Deadeye", SpriteID.Prayeron.DEADEYE, InterfaceID.Prayerbook.PRAYER23), + MYSTIC_MIGHT(23, "Mystic Might", SpriteID.Prayeron.MYSTIC_MIGHT, InterfaceID.Prayerbook.PRAYER24) + { + @Override + public int getUnlockVarbit() + { + return VarbitID.PRAYER_MYSTIC_VIGOUR_UNLOCKED; + } + + @Override + public Prayer getUnlockPrayer() + { + return MYSTIC_VIGOUR; + } + }, + MYSTIC_VIGOUR(-23, "Mystic Vigour", SpriteID.Prayeron.MYSTIC_VIGOUR, InterfaceID.Prayerbook.PRAYER24), + RETRIBUTION(15, "Retribution", SpriteID.Prayeron.RETRIBUTION, InterfaceID.Prayerbook.PRAYER16), + REDEMPTION(16, "Redemption", SpriteID.Prayeron.REDEMPTION, InterfaceID.Prayerbook.PRAYER17), + SMITE(17, "Smite", SpriteID.Prayeron.SMITE, InterfaceID.Prayerbook.PRAYER18), + PRESERVE(28, "Preserve", SpriteID.Prayeron.PRESERVE, InterfaceID.Prayerbook.PRAYER29), + CHIVALRY(25, "Chivalry", SpriteID.Prayeron.CHIVALRY, InterfaceID.Prayerbook.PRAYER26), + PIETY(26, "Piety", SpriteID.Prayeron.PIETY, InterfaceID.Prayerbook.PRAYER27), + RIGOUR(24, "Rigour", SpriteID.Prayeron.RIGOUR, InterfaceID.Prayerbook.PRAYER25), + AUGURY(27, "Augury", SpriteID.Prayeron.AUGURY, InterfaceID.Prayerbook.PRAYER28); private final int bit; private final String name; private final int spriteID; + private final int interfaceID; + private final int unlockVarbit = -1; + private final Prayer unlockPrayer = null; private static final Map BITS = new HashMap<>(); + private static final int NUMBER_OF_PRAYERS = 29; static { @@ -80,17 +116,27 @@ enum Prayer } } - static List fromVarb(int varb) + static List fromVarb(int varb, Client client) { final List ret = new ArrayList<>(); - for (int i = 0; i < values().length; i++) + for (int i = 0; i < NUMBER_OF_PRAYERS; i++) { if ((varb & 0x1) == 1) { - ret.add(BITS.get(i)); + Prayer p = BITS.get(i); + if (p.getUnlockVarbit() >= 0 && isUnlocked(client, p.getUnlockVarbit()) && p.getUnlockPrayer() != null) + { + p = p.getUnlockPrayer(); + } + ret.add(p); } varb = varb >> 1; } return ret; } + + static boolean isUnlocked(Client client, int varb) + { + return client.getVarbitValue(varb) != 0; + } } diff --git a/src/main/java/io/hydrox/quickprayerpreview/QuickPrayerPreviewConfig.java b/src/main/java/io/hydrox/quickprayerpreview/QuickPrayerPreviewConfig.java new file mode 100644 index 0000000..e845e0c --- /dev/null +++ b/src/main/java/io/hydrox/quickprayerpreview/QuickPrayerPreviewConfig.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020, Hydrox6 + * 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 io.hydrox.quickprayerpreview; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("QuickPrayerPreview") +public interface QuickPrayerPreviewConfig extends Config +{ + @ConfigItem( + keyName = "orbPreview", + name = "Orb tooltip", + description = "Show the quick prayer tooltip on the prayer orb.", + position = 0 + ) + default boolean isOrbPreview() + { + return true; + } + + @ConfigItem( + keyName = "prayerTabPreview", + name = "Tab preview", + description = "Show the quick prayers in the prayer tab.", + position = 10 + ) + default boolean isPrayerTabPreview() + { + return false; + } +} diff --git a/src/main/java/io/hydrox/quickprayerpreview/QuickPrayerPreviewOverlay.java b/src/main/java/io/hydrox/quickprayerpreview/QuickPrayerPreviewOverlay.java index 23b53b7..d60d487 100644 --- a/src/main/java/io/hydrox/quickprayerpreview/QuickPrayerPreviewOverlay.java +++ b/src/main/java/io/hydrox/quickprayerpreview/QuickPrayerPreviewOverlay.java @@ -25,7 +25,7 @@ package io.hydrox.quickprayerpreview; import net.runelite.api.Client; -import net.runelite.api.widgets.ComponentID; +import net.runelite.api.gameval.InterfaceID; import net.runelite.api.widgets.Widget; import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.config.TooltipPositionType; @@ -69,7 +69,7 @@ public QuickPrayerPreviewOverlay(Client client, QuickPrayerPreviewPlugin plugin, public Dimension render(Graphics2D graphics) { panelComponent.getChildren().clear(); - Widget orb = client.getWidget(ComponentID.MINIMAP_PRAYER_ORB); + Widget orb = client.getWidget(InterfaceID.Orbs.ORB_PRAYER); List prayers = plugin.getQuickPrayers(); if (prayers == null || orb == null || orb.isHidden() || orb.isSelfHidden()) { diff --git a/src/main/java/io/hydrox/quickprayerpreview/QuickPrayerPreviewPlugin.java b/src/main/java/io/hydrox/quickprayerpreview/QuickPrayerPreviewPlugin.java index 88196df..307dc29 100644 --- a/src/main/java/io/hydrox/quickprayerpreview/QuickPrayerPreviewPlugin.java +++ b/src/main/java/io/hydrox/quickprayerpreview/QuickPrayerPreviewPlugin.java @@ -24,14 +24,19 @@ */ package io.hydrox.quickprayerpreview; +import com.google.inject.Provides; import lombok.Getter; import net.runelite.api.Client; import net.runelite.api.events.VarbitChanged; +import net.runelite.api.gameval.VarbitID; +import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.events.ConfigChanged; import net.runelite.client.game.SpriteManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; + import javax.inject.Inject; import java.awt.Graphics; import java.awt.image.BufferedImage; @@ -42,12 +47,10 @@ @PluginDescriptor( name = "Quick Prayer Preview", description = "Preview your quick prayers by hovering over the orb", - tags = {"prayer","quick prayer","preview"} + tags = {"prayer", "quick prayer", "preview"} ) public class QuickPrayerPreviewPlugin extends Plugin { - private static final int QUICK_PRAYER_VARBIT = 4102; - @Inject private Client client; @@ -58,7 +61,13 @@ public class QuickPrayerPreviewPlugin extends Plugin private SpriteManager spriteManager; @Inject - private QuickPrayerPreviewOverlay overlay; + private QuickPrayerPreviewOverlay tooltipOverlay; + + @Inject + private QuickPrayerPreviewPrayerTabOverlay tabOverlay; + + @Inject + private QuickPrayerPreviewConfig config; @Getter private List quickPrayers; @@ -66,32 +75,84 @@ public class QuickPrayerPreviewPlugin extends Plugin private final Map prayerSprites = new HashMap<>(); + @Provides + QuickPrayerPreviewConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(QuickPrayerPreviewConfig.class); + } + @Override public void startUp() { - overlayManager.add(overlay); + if (config.isOrbPreview()) + { + overlayManager.add(tooltipOverlay); + } + if (config.isPrayerTabPreview()) + { + overlayManager.add(tabOverlay); + } } @Override public void shutDown() { - overlayManager.remove(overlay); + overlayManager.remove(tooltipOverlay); + overlayManager.remove(tabOverlay); } @Subscribe public void onVarbitChanged(VarbitChanged e) { - int varb = client.getVarbitValue(QUICK_PRAYER_VARBIT); + int varb = client.getVarbitValue(VarbitID.QUICKPRAYER_SELECTED); if (varb == quickPrayerVarb) { return; } quickPrayerVarb = varb; - quickPrayers = Prayer.fromVarb(varb); + quickPrayers = Prayer.fromVarb(varb, client); loadSprites(); } + @Subscribe + public void onConfigChanged(ConfigChanged configChanged) + { + if (!"QuickPrayerPreview".equals(configChanged.getGroup())) + { + return; + } + + if ("orbPreview".equals(configChanged.getKey())) + { + if (config.isOrbPreview() && !overlayManager.anyMatch(o -> o.equals(tooltipOverlay))) + { + overlayManager.add(tooltipOverlay); + } + if (!config.isOrbPreview()) + { + overlayManager.remove(tooltipOverlay); + } + } + + if ("prayerTabPreview".equals(configChanged.getKey())) + { + if (config.isPrayerTabPreview() && !overlayManager.anyMatch(o -> o.equals(tabOverlay))) + { + overlayManager.add(tabOverlay); + } + if (!config.isPrayerTabPreview()) + { + overlayManager.remove(tabOverlay); + } + } + } + + BufferedImage getSprite(int id) + { + return spriteManager.getSprite(id, 0); + } + private void loadSprites() { for (Prayer p : quickPrayers) diff --git a/src/main/java/io/hydrox/quickprayerpreview/QuickPrayerPreviewPrayerTabOverlay.java b/src/main/java/io/hydrox/quickprayerpreview/QuickPrayerPreviewPrayerTabOverlay.java new file mode 100644 index 0000000..46071f9 --- /dev/null +++ b/src/main/java/io/hydrox/quickprayerpreview/QuickPrayerPreviewPrayerTabOverlay.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2020, Hydrox6 + * 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 io.hydrox.quickprayerpreview; + +import net.runelite.api.Client; +import net.runelite.api.Point; +import net.runelite.api.gameval.InterfaceID; +import net.runelite.api.gameval.SpriteID; +import net.runelite.api.widgets.Widget; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; + +import javax.inject.Inject; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +public class QuickPrayerPreviewPrayerTabOverlay extends Overlay +{ + private final QuickPrayerPreviewPlugin plugin; + private final Client client; + + private BufferedImage selectedPrayerSprite = null; + + @Inject + protected QuickPrayerPreviewPrayerTabOverlay(QuickPrayerPreviewPlugin plugin, Client client) + { + this.plugin = plugin; + this.client = client; + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_WIDGETS); + setPriority(Overlay.PRIORITY_HIGH); + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (selectedPrayerSprite == null) + { + int prayerSelectedSpriteId = SpriteID.Miscgraphics._11; + BufferedImage img = plugin.getSprite(prayerSelectedSpriteId); + if (img != null) + { + BufferedImage norm = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB); + Graphics g = norm.getGraphics(); + g.drawImage(img, norm.getWidth() / 2 - img.getWidth() / 2, norm.getHeight() / 2 - img.getHeight() / 2, null); + selectedPrayerSprite = img; + } + } + + // Don't show when not prayer book is hidden, this also hides it when selecting quick prayers tab is open + Widget prayerbook = client.getWidget(InterfaceID.PRAYERBOOK, 0); + if (prayerbook == null || prayerbook.isHidden()) + { + return null; + } + + if (selectedPrayerSprite == null) + { + return null; + } + + for (Prayer quickPrayer : plugin.getQuickPrayers()) + { + Widget prayerWidget = client.getWidget(quickPrayer.getInterfaceID()); + if (prayerWidget == null || prayerWidget.isHidden()) + { + continue; + } + + Point canvasPoint = prayerWidget.getCanvasLocation(); + if (canvasPoint == null) + { + continue; + } + + graphics.drawImage(selectedPrayerSprite, canvasPoint.getX(), canvasPoint.getY(), null); + } + + return null; + } +} From 88093819de6b2ff6eda845bc3c3e99fa3e2c3e1e Mon Sep 17 00:00:00 2001 From: l2- <2605718+l2-@users.noreply.github.com> Date: Sun, 3 May 2026 14:20:51 +0200 Subject: [PATCH 2/2] Fix prayer interface IDs for Mystic Will and others --- src/main/java/io/hydrox/quickprayerpreview/Prayer.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/hydrox/quickprayerpreview/Prayer.java b/src/main/java/io/hydrox/quickprayerpreview/Prayer.java index a34643b..84069d0 100644 --- a/src/main/java/io/hydrox/quickprayerpreview/Prayer.java +++ b/src/main/java/io/hydrox/quickprayerpreview/Prayer.java @@ -44,22 +44,22 @@ enum Prayer BURST_OF_STRENGTH(1, "Burst of Strength", SpriteID.Prayeron.BURST_OF_STRENGTH, InterfaceID.Prayerbook.PRAYER2), CLARITY_OF_THOUGHT(2, "Clarity of Thought", SpriteID.Prayeron.CLARITY_OF_THOUGHT, InterfaceID.Prayerbook.PRAYER3), SHARP_EYE(18, "Sharp Eye", SpriteID.Prayeron.SHARP_EYE, InterfaceID.Prayerbook.PRAYER19), - MYSTIC_WILL(19, "Mystic Will", SpriteID.Prayeron.MYSTIC_WILL, InterfaceID.Prayerbook.PRAYER20), + MYSTIC_WILL(19, "Mystic Will", SpriteID.Prayeron.MYSTIC_WILL, InterfaceID.Prayerbook.PRAYER22), ROCK_SKIN(3, "Rock Skin", SpriteID.Prayeron.ROCK_SKIN, InterfaceID.Prayerbook.PRAYER4), SUPERHUMAN_STRENGTH(4, "Superhuman Strength", SpriteID.Prayeron.SUPERHUMAN_STRENGTH, InterfaceID.Prayerbook.PRAYER5), IMPROVED_REFLEXES(5, "Improved Reflexes", SpriteID.Prayeron.IMPROVED_REFLEXES, InterfaceID.Prayerbook.PRAYER6), RAPID_RESTORE(6, "Rapid Restore", SpriteID.Prayeron.RAPID_RESTORE, InterfaceID.Prayerbook.PRAYER7), RAPID_HEAL(7, "Rapid Heal", SpriteID.Prayeron.RAPID_HEAL, InterfaceID.Prayerbook.PRAYER8), PROTECT_ITEM(8, "Protect Item", SpriteID.Prayeron.PROTECT_ITEM, InterfaceID.Prayerbook.PRAYER9), - HAWK_EYE(20, "Hawk Eye", SpriteID.Prayeron.HAWK_EYE, InterfaceID.Prayerbook.PRAYER21), - MYSTIC_LORE(21, "Mystic Lore", SpriteID.Prayeron.MYSTIC_LORE, InterfaceID.Prayerbook.PRAYER22), + HAWK_EYE(20, "Hawk Eye", SpriteID.Prayeron.HAWK_EYE, InterfaceID.Prayerbook.PRAYER20), + MYSTIC_LORE(21, "Mystic Lore", SpriteID.Prayeron.MYSTIC_LORE, InterfaceID.Prayerbook.PRAYER23), STEEL_SKIN(9, "Steel Skin", SpriteID.Prayeron.STEEL_SKIN, InterfaceID.Prayerbook.PRAYER10), ULTIMATE_STRENGTH(10, "Ultimate Strength", SpriteID.Prayeron.ULTIMATE_STRENGTH, InterfaceID.Prayerbook.PRAYER11), INCREDIBLE_REFLEXES(11, "Incredible reflexes", SpriteID.Prayeron.INCREDIBLE_REFLEXES, InterfaceID.Prayerbook.PRAYER12), PROTECT_FROM_MAGIC(12, "protect from magic", SpriteID.Prayeron.PROTECT_FROM_MAGIC, InterfaceID.Prayerbook.PRAYER13), PROTECT_FROM_MISSILES(13, "Protect from missiles", SpriteID.Prayeron.PROTECT_FROM_MISSILES, InterfaceID.Prayerbook.PRAYER14), PROTECT_FROM_MELEE(14, "Protect from melee", SpriteID.Prayeron.PROTECT_FROM_MELEE, InterfaceID.Prayerbook.PRAYER15), - EAGLE_EYE(22, "Eagle Eye", SpriteID.Prayeron.EAGLE_EYE, InterfaceID.Prayerbook.PRAYER23) + EAGLE_EYE(22, "Eagle Eye", SpriteID.Prayeron.EAGLE_EYE, InterfaceID.Prayerbook.PRAYER21) { @Override public int getUnlockVarbit() @@ -73,7 +73,7 @@ public Prayer getUnlockPrayer() return DEADEYE; } }, - DEADEYE(-22, "Deadeye", SpriteID.Prayeron.DEADEYE, InterfaceID.Prayerbook.PRAYER23), + DEADEYE(-22, "Deadeye", SpriteID.Prayeron.DEADEYE, InterfaceID.Prayerbook.PRAYER21), MYSTIC_MIGHT(23, "Mystic Might", SpriteID.Prayeron.MYSTIC_MIGHT, InterfaceID.Prayerbook.PRAYER24) { @Override