Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -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.
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)
12 changes: 8 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down
112 changes: 79 additions & 33 deletions src/main/java/io/hydrox/quickprayerpreview/Prayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.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.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.PRAYER21)
{
@Override
public int getUnlockVarbit()
{
return VarbitID.PRAYER_DEADEYE_UNLOCKED;
}

@Override
public Prayer getUnlockPrayer()
{
return DEADEYE;
}
},
DEADEYE(-22, "Deadeye", SpriteID.Prayeron.DEADEYE, InterfaceID.Prayerbook.PRAYER21),
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<Integer, Prayer> BITS = new HashMap<>();
private static final int NUMBER_OF_PRAYERS = 29;

static
{
Expand All @@ -80,17 +116,27 @@ enum Prayer
}
}

static List<Prayer> fromVarb(int varb)
static List<Prayer> fromVarb(int varb, Client client)
{
final List<Prayer> 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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2020, Hydrox6 <ikada@protonmail.ch>
* 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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<Prayer> prayers = plugin.getQuickPrayers();
if (prayers == null || orb == null || orb.isHidden() || orb.isSelfHidden())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand All @@ -58,40 +61,98 @@ 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<Prayer> quickPrayers;
private int quickPrayerVarb = -1;

private final Map<Prayer, BufferedImage> 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)
Expand Down
Loading