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 6d94c9bebc..69d835a7c7 100644 --- a/runelite-api/src/main/java/net/runelite/api/Prayer.java +++ b/runelite-api/src/main/java/net/runelite/api/Prayer.java @@ -32,125 +32,128 @@ public enum Prayer /** * Thick Skin (Level 1, Defence). */ - THICK_SKIN(Varbits.PRAYER_THICK_SKIN), + THICK_SKIN(Varbits.PRAYER_THICK_SKIN, 5.0), /** * Burst of Strength (Level 4, Strength). */ - BURST_OF_STRENGTH(Varbits.PRAYER_BURST_OF_STRENGTH), + BURST_OF_STRENGTH(Varbits.PRAYER_BURST_OF_STRENGTH, 5.0), /** * Clarity of Thought (Level 7, Attack). */ - CLARITY_OF_THOUGHT(Varbits.PRAYER_CLARITY_OF_THOUGHT), + CLARITY_OF_THOUGHT(Varbits.PRAYER_CLARITY_OF_THOUGHT, 5.0), /** * Sharp Eye (Level 8, Ranging). */ - SHARP_EYE(Varbits.PRAYER_SHARP_EYE), + SHARP_EYE(Varbits.PRAYER_SHARP_EYE, 5.0), /** * Mystic Will (Level 9, Magic). */ - MYSTIC_WILL(Varbits.PRAYER_MYSTIC_WILL), + MYSTIC_WILL(Varbits.PRAYER_MYSTIC_WILL, 5.0), /** * Rock Skin (Level 10, Defence). */ - ROCK_SKIN(Varbits.PRAYER_ROCK_SKIN), + ROCK_SKIN(Varbits.PRAYER_ROCK_SKIN, 10.0), /** * Superhuman Strength (Level 13, Strength). */ - SUPERHUMAN_STRENGTH(Varbits.PRAYER_SUPERHUMAN_STRENGTH), + SUPERHUMAN_STRENGTH(Varbits.PRAYER_SUPERHUMAN_STRENGTH, 10.0), /** * Improved Reflexes (Level 16, Attack). */ - IMPROVED_REFLEXES(Varbits.PRAYER_IMPROVED_REFLEXES), + IMPROVED_REFLEXES(Varbits.PRAYER_IMPROVED_REFLEXES, 10.0), /** * Rapid Restore (Level 19, Stats). */ - RAPID_RESTORE(Varbits.PRAYER_RAPID_RESTORE), + RAPID_RESTORE(Varbits.PRAYER_RAPID_RESTORE, 60.0 / 36.0), /** * Rapid Heal (Level 22, Hitpoints). */ - RAPID_HEAL(Varbits.PRAYER_RAPID_HEAL), + RAPID_HEAL(Varbits.PRAYER_RAPID_HEAL, 60.0 / 18), /** * Protect Item (Level 25). */ - PROTECT_ITEM(Varbits.PRAYER_PROTECT_ITEM), + PROTECT_ITEM(Varbits.PRAYER_PROTECT_ITEM, 60.0 / 18), /** * Hawk Eye (Level 26, Ranging). */ - HAWK_EYE(Varbits.PRAYER_HAWK_EYE), + HAWK_EYE(Varbits.PRAYER_HAWK_EYE, 10.0), /** * Mystic Lore (Level 27, Magic). */ - MYSTIC_LORE(Varbits.PRAYER_MYSTIC_LORE), + MYSTIC_LORE(Varbits.PRAYER_MYSTIC_LORE, 10.0), /** * Steel Skin (Level 28, Defence). */ - STEEL_SKIN(Varbits.PRAYER_STEEL_SKIN), + STEEL_SKIN(Varbits.PRAYER_STEEL_SKIN, 20.0), /** * Ultimate Strength (Level 31, Strength). */ - ULTIMATE_STRENGTH(Varbits.PRAYER_ULTIMATE_STRENGTH), + ULTIMATE_STRENGTH(Varbits.PRAYER_ULTIMATE_STRENGTH, 20.0), /** * Incredible Reflexes (Level 34, Attack). */ - INCREDIBLE_REFLEXES(Varbits.PRAYER_INCREDIBLE_REFLEXES), + INCREDIBLE_REFLEXES(Varbits.PRAYER_INCREDIBLE_REFLEXES, 20.0), /** * Protect from Magic (Level 37). */ - PROTECT_FROM_MAGIC(Varbits.PRAYER_PROTECT_FROM_MAGIC), + PROTECT_FROM_MAGIC(Varbits.PRAYER_PROTECT_FROM_MAGIC, 20.0), /** * Protect from Missiles (Level 40). */ - PROTECT_FROM_MISSILES(Varbits.PRAYER_PROTECT_FROM_MISSILES), + PROTECT_FROM_MISSILES(Varbits.PRAYER_PROTECT_FROM_MISSILES, 20.0), /** * Protect from Melee (Level 43). */ - PROTECT_FROM_MELEE(Varbits.PRAYER_PROTECT_FROM_MELEE), + PROTECT_FROM_MELEE(Varbits.PRAYER_PROTECT_FROM_MELEE, 20.0), /** * Eagle Eye (Level 44, Ranging). */ - EAGLE_EYE(Varbits.PRAYER_EAGLE_EYE), + EAGLE_EYE(Varbits.PRAYER_EAGLE_EYE, 20.0), /** * Mystic Might (Level 45, Magic). */ - MYSTIC_MIGHT(Varbits.PRAYER_MYSTIC_MIGHT), + MYSTIC_MIGHT(Varbits.PRAYER_MYSTIC_MIGHT, 20.0), /** * Retribution (Level 46). */ - RETRIBUTION(Varbits.PRAYER_RETRIBUTION), + RETRIBUTION(Varbits.PRAYER_RETRIBUTION, 5.0), /** * Redemption (Level 49). */ - REDEMPTION(Varbits.PRAYER_REDEMPTION), + REDEMPTION(Varbits.PRAYER_REDEMPTION, 10.0), /** * Smite (Level 52). */ - SMITE(Varbits.PRAYER_SMITE), + SMITE(Varbits.PRAYER_SMITE, 30.0), /** * Chivalry (Level 60, Defence/Strength/Attack). */ - CHIVALRY(Varbits.PRAYER_CHIVALRY), + CHIVALRY(Varbits.PRAYER_CHIVALRY, 40.0), /** * Piety (Level 70, Defence/Strength/Attack). */ - PIETY(Varbits.PRAYER_PIETY), + PIETY(Varbits.PRAYER_PIETY, 40.0), /** * Preserve (Level 55). */ - PRESERVE(Varbits.PRAYER_PRESERVE), + PRESERVE(Varbits.PRAYER_PRESERVE, 60.0 / 18), /** * Rigour (Level 74, Ranging/Damage/Defence). */ - RIGOUR(Varbits.PRAYER_RIGOUR), + RIGOUR(Varbits.PRAYER_RIGOUR, 40.0), /** * Augury (Level 77, Magic/Magic Def./Defence). */ - AUGURY(Varbits.PRAYER_AUGURY); + AUGURY(Varbits.PRAYER_AUGURY, 40.0); private final Varbits varbit; - Prayer(Varbits varbit) + private final double drainRate; + + Prayer(Varbits varbit, double drainRate) { this.varbit = varbit; + this.drainRate = drainRate; } /** @@ -162,4 +165,14 @@ 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-client/src/main/java/net/runelite/client/plugins/prayer/PrayerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerConfig.java index 553c5060ed..47a83d7b13 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerConfig.java @@ -67,4 +67,26 @@ public interface PrayerConfig extends Config { return false; } + + @ConfigItem( + position = 3, + keyName = "showPrayerDoseIndicator", + name = "Show Prayer Dose Indicator", + description = "Enables the prayer dose indicator." + ) + default boolean showPrayerDoseIndicator() + { + return true; + } + + @ConfigItem( + position = 4, + keyName = "Statistics", + name = "Show Prayer Stats", + description = "Displays time remaining and prayer bonus as a tooltip on the quick-prayer icon." + ) + default boolean showPrayerStatistics() + { + return true; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerDoseOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerDoseOverlay.java new file mode 100644 index 0000000000..3566cca345 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerDoseOverlay.java @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2018, Ethan + * 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.prayer; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.time.Duration; +import java.time.Instant; +import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Setter; +import net.runelite.api.Client; +import net.runelite.api.Point; +import net.runelite.api.Prayer; +import net.runelite.api.Skill; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.tooltip.Tooltip; +import net.runelite.client.ui.overlay.tooltip.TooltipManager; +import net.runelite.client.util.SwingUtil; +import org.apache.commons.lang3.StringUtils; + +public class PrayerDoseOverlay extends Overlay +{ + private static final float PULSE_TIME = 1200f; + + private static final Color START_COLOR = new Color(0, 255, 255); + private static final Color END_COLOR = new Color(0, 92, 92); + + private final Client client; + private final PrayerConfig config; + private final TooltipManager tooltipManager; + private Instant startOfLastTick = Instant.now(); + private boolean trackTick = true; + + @Setter(AccessLevel.PACKAGE) + private int prayerBonus; + @Setter(AccessLevel.PACKAGE) + private boolean hasPrayerPotion; + @Setter(AccessLevel.PACKAGE) + private boolean hasRestorePotion; + @Setter(AccessLevel.PACKAGE) + private boolean hasHolyWrench; + + @Inject + private PrayerDoseOverlay(final Client client, final TooltipManager tooltipManager, final PrayerConfig config) + { + this.client = client; + this.tooltipManager = tooltipManager; + this.config = config; + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_WIDGETS); + } + + void onTick() + { + // Only track the time on every other tick + if (trackTick) + { + startOfLastTick = Instant.now(); //Reset the tick timer + trackTick = false; + } + else + { + trackTick = true; + } + } + + @Override + public Dimension render(Graphics2D graphics) + { + final Widget xpOrb = client.getWidget(WidgetInfo.QUICK_PRAYER_ORB); + if (xpOrb == null) + { + return null; + } + + final Rectangle bounds = xpOrb.getBounds(); + if (bounds.getX() <= 0) + { + return null; + } + + final Point mousePosition = client.getMouseCanvasPosition(); + + if (config.showPrayerStatistics() && bounds.contains(mousePosition.getX(), mousePosition.getY())) + { + final String tooltip = "Time Remaining: " + getEstimatedTimeRemaining() + + "
" + + "Prayer Bonus: " + prayerBonus; + + tooltipManager.add(new Tooltip(tooltip)); + } + + if (!config.showPrayerDoseIndicator() || (!hasPrayerPotion && !hasRestorePotion)) + { + return null; + } + + final int currentPrayer = client.getBoostedSkillLevel(Skill.PRAYER); + final int maxPrayer = client.getRealSkillLevel(Skill.PRAYER); + + final int prayerPointsMissing = maxPrayer - currentPrayer; + if (prayerPointsMissing <= 0) + { + return null; + } + + final double dosePercentage = hasHolyWrench ? .27 : .25; + final int basePointsRestored = (int) Math.floor(maxPrayer * dosePercentage); + + // how many points a prayer and super restore will heal + final int prayerPotionPointsRestored = basePointsRestored + 7; + final int superRestorePointsRestored = basePointsRestored + 8; + + final boolean usePrayerPotion = prayerPointsMissing >= prayerPotionPointsRestored; + final boolean useSuperRestore = prayerPointsMissing >= superRestorePointsRestored; + + if (!usePrayerPotion && !useSuperRestore) + { + return null; + } + + // Purposefully using height twice here as the bounds of the prayer orb includes the number sticking out the side + final int orbInnerSize = (int) bounds.getHeight(); + + final int orbInnerX = (int) (bounds.getX() + 24); // x pos of the inside of the prayer orb + final int orbInnerY = (int) (bounds.getY() - 1); // y pos of the inside of the prayer orb + + final long timeSinceLastTick = Duration.between(startOfLastTick, Instant.now()).toMillis(); + + final float tickProgress = Math.min(timeSinceLastTick / PULSE_TIME, 1); // Cap between 0 and 1 + final double t = tickProgress * Math.PI; // Convert to 0 - pi + + graphics.setColor(SwingUtil.colorLerp(START_COLOR, END_COLOR, Math.sin(t))); + graphics.setStroke(new BasicStroke(2)); + graphics.drawOval(orbInnerX, orbInnerY, orbInnerSize, orbInnerSize); + + return new Dimension((int) bounds.getWidth(), (int) bounds.getHeight()); + } + + private double getPrayerDrainRate(Client client) + { + double drainRate = 0.0; + + for (Prayer prayer : Prayer.values()) + { + if (client.isPrayerActive(prayer)) + { + drainRate += prayer.getDrainRate(); + } + } + + return drainRate; + } + + private String getEstimatedTimeRemaining() + { + // Base data + final double drainRate = getPrayerDrainRate(client); + + if (drainRate == 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)); + + // Calculate the number of seconds left + final double secondsLeft = (currentPrayer * secondsPerPoint); + final int minutes = (int) Math.floor(secondsLeft / 60.0); + final int seconds = (int) Math.floor(secondsLeft - (minutes * 60.0)); + + // Return the text + return Integer.toString(minutes) + ":" + StringUtils.leftPad(Integer.toString(seconds), 2, "0"); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerFlickOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerFlickOverlay.java index b434f596ec..29657ee9e3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerFlickOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerFlickOverlay.java @@ -53,7 +53,7 @@ public class PrayerFlickOverlay extends Overlay this.client = client; } - public void onTick() + void onTick() { startOfLastTick = Instant.now(); //Reset the tick timer prayersActive = isAnyPrayerActive(); //Check if prayers are active diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerItems.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerItems.java new file mode 100644 index 0000000000..81e307bc2c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerItems.java @@ -0,0 +1,461 @@ +/* + * Copyright (c) 2018, Ethan + * 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.prayer; + +import java.util.HashMap; +import java.util.Map; +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.runelite.api.ItemID; + +@AllArgsConstructor +@Getter +public enum PrayerItems +{ + // Blessings + PEACEFUL_BLESSING(ItemID.PEACEFUL_BLESSING, 1), + HOLY_BLESSING(ItemID.HOLY_BLESSING, 1), + UNHOLY_BLESSING(ItemID.UNHOLY_BLESSING, 1), + ANCIENT_BLESSING(ItemID.ANCIENT_BLESSING, 1), + HONOURABLE_BLESSING(ItemID.HONOURABLE_BLESSING, 1), + WAR_BLESSING(ItemID.WAR_BLESSING, 1), + + // Rings + EXPLORERS_RING(ItemID.EXPLORERS_RING, 1), + EXPLORERS_RING_1(ItemID.EXPLORERS_RING_1, 1), + EXPLORERS_RING_2(ItemID.EXPLORERS_RING_2, 1), + EXPLORERS_RING_3(ItemID.EXPLORERS_RING_3, 1), + EXPLORERS_RING_4(ItemID.EXPLORERS_RING_4, 1), + RING_OF_SUFFERING(ItemID.RING_OF_SUFFERING, 2), + RING_OF_SUFFERING_I(ItemID.RING_OF_SUFFERING_I, 4), + RING_OF_THE_GODS(ItemID.RING_OF_THE_GODS, 4), + RING_OF_THE_GODS_I(ItemID.RING_OF_THE_GODS_I, 8), + + // Necklaces + AMULET_OF_POWER(ItemID.AMULET_OF_POWER, 1), + BEADS_OF_THE_DEAD(ItemID.BEADS_OF_THE_DEAD, 1), + OCCULT_NECKLACE(ItemID.OCCULT_NECKLACE, 2), + OCCULT_NECKLACE_OR(ItemID.OCCULT_NECKLACE_OR, 2), + AMULET_OF_TORTURE(ItemID.AMULET_OF_TORTURE, 2), + AMULET_OF_TORTURE_OR(ItemID.AMULET_OF_TORTURE_OR, 2), + NECKLACE_OF_ANGUISH(ItemID.NECKLACE_OF_ANGUISH, 2), + NECKLACE_OF_ANGUISH_OR(ItemID.NECKLACE_OF_ANGUISH_OR, 2), + AMULET_OF_GLORY(ItemID.AMULET_OF_GLORY, 3), + AMULET_OF_GLORY1(ItemID.AMULET_OF_GLORY1, 3), + AMULET_OF_GLORY2(ItemID.AMULET_OF_GLORY2, 3), + AMULET_OF_GLORY3(ItemID.AMULET_OF_GLORY3, 3), + AMULET_OF_GLORY4(ItemID.AMULET_OF_GLORY4, 3), + AMULET_OF_GLORY5(ItemID.AMULET_OF_GLORY5, 3), + AMULET_OF_GLORY6(ItemID.AMULET_OF_GLORY6, 3), + AMULET_OF_GLORY_T(ItemID.AMULET_OF_GLORY_T, 3), + AMULET_OF_GLORY_T1(ItemID.AMULET_OF_GLORY_T1, 3), + AMULET_OF_GLORY_T2(ItemID.AMULET_OF_GLORY_T2, 3), + AMULET_OF_GLORY_T3(ItemID.AMULET_OF_GLORY_T3, 3), + AMULET_OF_GLORY_T4(ItemID.AMULET_OF_GLORY_T4, 3), + AMULET_OF_GLORY_T5(ItemID.AMULET_OF_GLORY_T5, 3), + AMULET_OF_GLORY_T6(ItemID.AMULET_OF_GLORY_T6, 3), + AMULET_OF_ETERNAL_GLORY(ItemID.AMULET_OF_ETERNAL_GLORY, 3), + AMULET_OF_GLORY_8283(ItemID.AMULET_OF_GLORY_8283, 3), + AMULET_OF_GLORY_20586(ItemID.AMULET_OF_GLORY_20586, 3), + AMULET_OF_GLORY_T_10719(ItemID.AMULET_OF_GLORY_T_10719, 3), + SALVE_AMULET(ItemID.SALVE_AMULET, 3), + SALVE_AMULET_E(ItemID.SALVE_AMULET_E, 3), + SALVE_AMULETEI(ItemID.SALVE_AMULETEI, 3), + SALVE_AMULETI(ItemID.SALVE_AMULETI, 3), + AMULET_OF_FURY(ItemID.AMULET_OF_FURY, 5), + AMULET_OF_FURY_OR(ItemID.AMULET_OF_FURY_OR, 5), + HOLY_SYMBOL(ItemID.HOLY_SYMBOL, 8), + HOLY_SYMBOL_4682(ItemID.HOLY_SYMBOL_4682, 8), + UNHOLY_SYMBOL(ItemID.UNHOLY_SYMBOL, 8), + UNHOLY_SYMBOL_4683(ItemID.UNHOLY_SYMBOL_4683, 8), + ANCIENT_STOLE(ItemID.ANCIENT_STOLE, 10), + ARMADYL_STOLE(ItemID.ARMADYL_STOLE, 10), + BANDOS_STOLE(ItemID.BANDOS_STOLE, 10), + GUTHIX_STOLE(ItemID.GUTHIX_STOLE, 10), + SARADOMIN_STOLE(ItemID.SARADOMIN_STOLE, 10), + ZAMORAK_STOLE(ItemID.ZAMORAK_STOLE, 10), + DRAGONBONE_NECKLACE(ItemID.DRAGONBONE_NECKLACE, 12), + + // Helmet + ARMADYL_HELMET(ItemID.ARMADYL_HELMET, 1), + ANCIENT_COIF(ItemID.ANCIENT_COIF, 1), + ARMADYL_COIF(ItemID.ARMADYL_COIF, 1), + BANDOS_COIF(ItemID.BANDOS_COIF, 1), + GUTHIX_COIF(ItemID.GUTHIX_COIF, 1), + SARADOMIN_COIF(ItemID.SARADOMIN_COIF, 1), + ZAMORAK_COIF(ItemID.ZAMORAK_COIF, 1), + WHITE_FULL_HELM(ItemID.WHITE_FULL_HELM, 1), + WHITE_MED_HELM(ItemID.WHITE_MED_HELM, 1), + ANCIENT_FULL_HELM(ItemID.ANCIENT_FULL_HELM, 1), + ARMADYL_FULL_HELM(ItemID.ARMADYL_FULL_HELM, 1), + BANDOS_FULL_HELM(ItemID.BANDOS_FULL_HELM, 1), + GUTHIX_FULL_HELM(ItemID.GUTHIX_FULL_HELM, 1), + SARADOMIN_FULL_HELM(ItemID.SARADOMIN_FULL_HELM, 1), + ZAMORAK_FULL_HELM(ItemID.ZAMORAK_FULL_HELM, 1), + HELM_OF_NEITIZNOT(ItemID.HELM_OF_NEITIZNOT, 3), + INITIATE_SALLET(ItemID.INITIATE_SALLET, 3), + VERACS_HELM(ItemID.VERACS_HELM, 3), + VERACS_HELM_0(ItemID.VERACS_HELM_0, 3), + VERACS_HELM_25(ItemID.VERACS_HELM_25, 3), + VERACS_HELM_50(ItemID.VERACS_HELM_50, 3), + VERACS_HELM_75(ItemID.VERACS_HELM_75, 3), + VERACS_HELM_100(ItemID.VERACS_HELM_100, 3), + GUTHIX_HALO(ItemID.GUTHIX_HALO, 3), + SARADOMIN_HALO(ItemID.SARADOMIN_HALO, 3), + ZAMORAK_HALO(ItemID.ZAMORAK_HALO, 3), + PROSELYTE_SALLET(ItemID.PROSELYTE_SALLET, 4), + PROSELYTE_SALLET_20563(ItemID.PROSELYTE_SALLET_20563, 4), + ANCIENT_MITRE(ItemID.ANCIENT_MITRE, 5), + ARMADYL_MITRE(ItemID.ARMADYL_MITRE, 5), + BANDOS_MITRE(ItemID.BANDOS_MITRE, 5), + GUTHIX_MITRE(ItemID.GUTHIX_MITRE, 5), + SARADOMIN_MITRE(ItemID.SARADOMIN_MITRE, 5), + ZAMORAK_MITRE(ItemID.ZAMORAK_MITRE, 5), + + // Body + ARMADYL_CHESTPLATE(ItemID.ARMADYL_CHESTPLATE, 1), + BANDOS_CHESTPLATE(ItemID.BANDOS_CHESTPLATE, 1), + ANCIENT_DHIDE(ItemID.ANCIENT_DHIDE, 1), + ARMADYL_DHIDE(ItemID.ARMADYL_DHIDE, 1), + BANDOS_DHIDE(ItemID.BANDOS_DHIDE, 1), + GUTHIX_DRAGONHIDE(ItemID.GUTHIX_DRAGONHIDE, 1), + GUTHIX_DRAGONHIDE_10794(ItemID.GUTHIX_DRAGONHIDE_10794, 1), + SARADOMIN_DHIDE(ItemID.SARADOMIN_DHIDE, 1), + SARADOMIN_DHIDE_10792(ItemID.SARADOMIN_DHIDE_10792, 1), + ZAMORAK_DHIDE(ItemID.ZAMORAK_DHIDE, 1), + ZAMORAK_DHIDE_10790(ItemID.ZAMORAK_DHIDE_10790, 1), + WHITE_PLATEBODY(ItemID.WHITE_PLATEBODY, 1), + WHITE_PLATEBODY_10618(ItemID.WHITE_PLATEBODY_10618, 1), + WHITE_CHAINBODY(ItemID.WHITE_CHAINBODY, 1), + ANCIENT_PLATEBODY(ItemID.ANCIENT_PLATEBODY, 1), + ARMADYL_PLATEBODY(ItemID.ARMADYL_PLATEBODY, 1), + BANDOS_PLATEBODY(ItemID.BANDOS_PLATEBODY, 1), + GUTHIX_PLATEBODY(ItemID.GUTHIX_PLATEBODY, 1), + GUTHIX_PLATEBODY_10780(ItemID.GUTHIX_PLATEBODY_10780, 1), + SARADOMIN_PLATEBODY(ItemID.SARADOMIN_PLATEBODY, 1), + ZAMORAK_PLATEBODY(ItemID.ZAMORAK_PLATEBODY, 1), + ZAMORAK_PLATEBODY_10776(ItemID.ZAMORAK_PLATEBODY_10776, 1), + ZAMORAK_ROBE_1035(ItemID.ZAMORAK_ROBE_1035, 3), + ELITE_VOID_TOP(ItemID.ELITE_VOID_TOP, 3), + ELITE_VOID_TOP_BROKEN(ItemID.ELITE_VOID_TOP_BROKEN, 3), + PRIEST_GOWN(ItemID.PRIEST_GOWN, 3), + DRUIDS_ROBE_TOP(ItemID.DRUIDS_ROBE_TOP, 4), + VERACS_BRASSARD(ItemID.VERACS_BRASSARD, 5), + VERACS_BRASSARD_0(ItemID.VERACS_BRASSARD_0, 5), + VERACS_BRASSARD_25(ItemID.VERACS_BRASSARD_25, 5), + VERACS_BRASSARD_50(ItemID.VERACS_BRASSARD_50, 5), + VERACS_BRASSARD_75(ItemID.VERACS_BRASSARD_75, 5), + VERACS_BRASSARD_100(ItemID.VERACS_BRASSARD_100, 5), + SHADE_ROBE_TOP(ItemID.SHADE_ROBE_TOP, 5), + MONKS_ROBE_TOP(ItemID.MONKS_ROBE_TOP, 6), + MONKS_ROBE_TOP_G(ItemID.MONKS_ROBE_TOP_G, 6), + INITIATE_HAUBERK(ItemID.INITIATE_HAUBERK, 6), + INITIATE_HAUBERK_10619(ItemID.INITIATE_HAUBERK_10619, 6), + ANCIENT_ROBE_TOP(ItemID.ANCIENT_ROBE_TOP, 6), + ARMADYL_ROBE_TOP(ItemID.ARMADYL_ROBE_TOP, 6), + BANDOS_ROBE_TOP(ItemID.BANDOS_ROBE_TOP, 6), + GUTHIX_ROBE_TOP(ItemID.GUTHIX_ROBE_TOP, 6), + SARADOMIN_ROBE_TOP(ItemID.SARADOMIN_ROBE_TOP, 6), + ZAMORAK_ROBE_TOP(ItemID.ZAMORAK_ROBE_TOP, 6), + PROSELYTE_HAUBERK(ItemID.PROSELYTE_HAUBERK, 8), + PROSELYTE_HAUBERK_10620(ItemID.PROSELYTE_HAUBERK_10620, 8), + PROSELYTE_HAUBERK_20564(ItemID.PROSELYTE_HAUBERK_20564, 8), + + // Legs + ARMADYL_CHAINSKIRT(ItemID.ARMADYL_CHAINSKIRT, 1), + BANDOS_TASSETS(ItemID.BANDOS_TASSETS, 1), + ANCIENT_CHAPS(ItemID.ANCIENT_CHAPS, 1), + ARMADYL_CHAPS(ItemID.ARMADYL_CHAPS, 1), + BANDOS_CHAPS(ItemID.BANDOS_CHAPS, 1), + GUTHIX_CHAPS(ItemID.GUTHIX_CHAPS, 1), + SARADOMIN_CHAPS(ItemID.SARADOMIN_CHAPS, 1), + ZAMORAK_CHAPS(ItemID.ZAMORAK_CHAPS, 1), + WHITE_PLATELEGS(ItemID.WHITE_PLATELEGS, 1), + WHITE_PLATESKIRT(ItemID.WHITE_PLATESKIRT, 1), + ANCIENT_PLATELEGS(ItemID.ANCIENT_PLATELEGS, 1), + ANCIENT_PLATESKIRT(ItemID.ANCIENT_PLATESKIRT, 1), + ARMADYL_PLATELEGS(ItemID.ARMADYL_PLATELEGS, 1), + ARMADYL_PLATESKIRT(ItemID.ARMADYL_PLATESKIRT, 1), + BANDOS_PLATELEGS(ItemID.BANDOS_PLATELEGS, 1), + BANDOS_PLATESKIRT(ItemID.BANDOS_PLATESKIRT, 1), + GUTHIX_PLATELEGS(ItemID.GUTHIX_PLATELEGS, 1), + GUTHIX_PLATESKIRT(ItemID.GUTHIX_PLATESKIRT, 1), + SARADOMIN_PLATELEGS(ItemID.SARADOMIN_PLATELEGS, 1), + SARADOMIN_PLATESKIRT(ItemID.SARADOMIN_PLATESKIRT, 1), + ZAMORAK_PLATELEGS(ItemID.ZAMORAK_PLATELEGS, 1), + ZAMORAK_PLATESKIRT(ItemID.ZAMORAK_PLATESKIRT, 1), + ZAMORAK_ROBE(ItemID.ZAMORAK_ROBE, 3), + ELITE_VOID_ROBE(ItemID.ELITE_VOID_ROBE, 3), + ELITE_VOID_ROBE_BROKEN(ItemID.ELITE_VOID_ROBE_BROKEN, 3), + PRIEST_GOWN_428(ItemID.PRIEST_GOWN_428, 3), + DRUIDS_ROBE(ItemID.DRUIDS_ROBE, 4), + SHADE_ROBE(ItemID.SHADE_ROBE, 4), + VERACS_PLATESKIRT(ItemID.VERACS_PLATESKIRT, 4), + VERACS_PLATESKIRT_0(ItemID.VERACS_PLATESKIRT_0, 4), + VERACS_PLATESKIRT_25(ItemID.VERACS_PLATESKIRT_25, 4), + VERACS_PLATESKIRT_50(ItemID.VERACS_PLATESKIRT_50, 4), + VERACS_PLATESKIRT_75(ItemID.VERACS_PLATESKIRT_75, 4), + VERACS_PLATESKIRT_100(ItemID.VERACS_PLATESKIRT_100, 4), + MONKS_ROBE(ItemID.MONKS_ROBE, 5), + MONKS_ROBE_G(ItemID.MONKS_ROBE_G, 5), + INITIATE_CUISSE(ItemID.INITIATE_CUISSE, 5), + ANCIENT_ROBE_LEGS(ItemID.ANCIENT_ROBE_LEGS, 5), + ARMADYL_ROBE_LEGS(ItemID.ARMADYL_ROBE_LEGS, 5), + BANDOS_ROBE_LEGS(ItemID.BANDOS_ROBE_LEGS, 5), + GUTHIX_ROBE_LEGS(ItemID.GUTHIX_ROBE_LEGS, 5), + SARADOMIN_ROBE_LEGS(ItemID.SARADOMIN_ROBE_LEGS, 5), + ZAMORAK_ROBE_LEGS(ItemID.ZAMORAK_ROBE_LEGS, 5), + PROSELYTE_CUISSE(ItemID.PROSELYTE_CUISSE, 6), + PROSELYTE_CUISSE_20565(ItemID.PROSELYTE_CUISSE_20565, 6), + PROSELYTE_TASSET(ItemID.PROSELYTE_TASSET, 6), + + // Boots + BANDOS_BOOTS(ItemID.BANDOS_BOOTS, 1), + WHITE_BOOTS(ItemID.WHITE_BOOTS, 1), + ANCIENT_DHIDE_BOOTS(ItemID.ANCIENT_DHIDE_BOOTS, 1), + ARMADYL_DHIDE_BOOTS(ItemID.ARMADYL_DHIDE_BOOTS, 1), + BANDOS_DHIDE_BOOTS(ItemID.BANDOS_DHIDE_BOOTS, 1), + GUTHIX_DHIDE_BOOTS(ItemID.GUTHIX_DHIDE_BOOTS, 1), + SARADOMIN_DHIDE_BOOTS(ItemID.SARADOMIN_DHIDE_BOOTS, 1), + ZAMORAK_DHIDE_BOOTS(ItemID.ZAMORAK_DHIDE_BOOTS, 1), + GUARDIAN_BOOTS(ItemID.GUARDIAN_BOOTS, 2), + HOLY_SANDALS(ItemID.HOLY_SANDALS, 3), + + // Gloves + ANCIENT_BRACERS(ItemID.ANCIENT_BRACERS, 1), + ARMADYL_BRACERS(ItemID.ARMADYL_BRACERS, 1), + BANDOS_BRACERS(ItemID.BANDOS_BRACERS, 1), + GUTHIX_BRACERS(ItemID.GUTHIX_BRACERS, 1), + SARADOMIN_BRACERS(ItemID.SARADOMIN_BRACERS, 1), + ZAMORAK_BRACERS(ItemID.ZAMORAK_BRACERS, 1), + WHITE_GLOVES(ItemID.WHITE_GLOVES, 1), + TORMENTED_BRACELET(ItemID.TORMENTED_BRACELET, 2), + HOLY_WRAPS(ItemID.HOLY_WRAPS, 3), + + // Capes + MYTHICAL_CAPE(ItemID.MYTHICAL_CAPE, 1), + MYTHICAL_CAPE_22114(ItemID.MYTHICAL_CAPE_22114, 1), + FIRE_CAPE(ItemID.FIRE_CAPE, 2), + FIRE_CAPE_10566(ItemID.FIRE_CAPE_10566, 2), + FIRE_CAPE_10637(ItemID.FIRE_CAPE_10637, 2), + FIRE_CAPE_BROKEN(ItemID.FIRE_CAPE_BROKEN, 2), + INFERNAL_CAPE(ItemID.INFERNAL_CAPE, 2), + INFERNAL_CAPE_21297(ItemID.INFERNAL_CAPE_21297, 2), + INFERNAL_CAPE_BROKEN(ItemID.INFERNAL_CAPE_BROKEN, 2), + ARDOUGNE_CLOAK_1(ItemID.ARDOUGNE_CLOAK_1, 2), + ANCIENT_CLOAK(ItemID.ANCIENT_CLOAK, 3), + ARMADYL_CLOAK(ItemID.ARMADYL_CLOAK, 3), + BANDOS_CLOAK(ItemID.BANDOS_CLOAK, 3), + GUTHIX_CLOAK(ItemID.GUTHIX_CLOAK, 3), + SARADOMIN_CLOAK(ItemID.SARADOMIN_CLOAK, 3), + ZAMORAK_CLOAK(ItemID.ZAMORAK_CLOAK, 3), + ATTACK_CAPET(ItemID.ATTACK_CAPET, 4), + STRENGTH_CAPET(ItemID.STRENGTH_CAPET, 4), + DEFENCE_CAPET(ItemID.DEFENCE_CAPET, 4), + RANGING_CAPET(ItemID.RANGING_CAPET, 4), + PRAYER_CAPET(ItemID.PRAYER_CAPET, 4), + MAGIC_CAPET(ItemID.MAGIC_CAPET, 4), + RUNECRAFT_CAPET(ItemID.RUNECRAFT_CAPET, 4), + CONSTRUCT_CAPET(ItemID.CONSTRUCT_CAPET, 4), + HITPOINTS_CAPET(ItemID.HITPOINTS_CAPET, 4), + AGILITY_CAPET(ItemID.AGILITY_CAPET, 4), + HERBLORE_CAPET(ItemID.HERBLORE_CAPET, 4), + THIEVING_CAPET(ItemID.THIEVING_CAPET, 4), + CRAFTING_CAPET(ItemID.CRAFTING_CAPET, 4), + FLETCHING_CAPET(ItemID.FLETCHING_CAPET, 4), + SLAYER_CAPET(ItemID.SLAYER_CAPET, 4), + HUNTER_CAPET(ItemID.HUNTER_CAPET, 4), + MINING_CAPET(ItemID.MINING_CAPET, 4), + SMITHING_CAPET(ItemID.SMITHING_CAPET, 4), + FISHING_CAPET(ItemID.FISHING_CAPET, 4), + COOKING_CAPET(ItemID.COOKING_CAPET, 4), + FIREMAKING_CAPET(ItemID.FIREMAKING_CAPET, 4), + WOODCUT_CAPET(ItemID.WOODCUT_CAPET, 4), + FARMING_CAPET(ItemID.FARMING_CAPET, 4), + QUEST_POINT_CAPE_T(ItemID.QUEST_POINT_CAPE_T, 4), + MUSIC_CAPET(ItemID.MUSIC_CAPET, 4), + ACHIEVEMENT_DIARY_CAPE(ItemID.ACHIEVEMENT_DIARY_CAPE, 4), + ACHIEVEMENT_DIARY_CAPE_T(ItemID.ACHIEVEMENT_DIARY_CAPE_T, 4), + MAX_CAPE(ItemID.MAX_CAPE, 4), + MAX_CAPE_13282(ItemID.MAX_CAPE_13282, 4), + MAX_CAPE_13342(ItemID.MAX_CAPE_13342, 4), + ACCUMULATOR_MAX_CAPE(ItemID.ACCUMULATOR_MAX_CAPE, 4), + ARDOUGNE_MAX_CAPE(ItemID.ARDOUGNE_MAX_CAPE, 4), + ASSEMBLER_MAX_CAPE(ItemID.ASSEMBLER_MAX_CAPE, 4), + ASSEMBLER_MAX_CAPE_BROKEN(ItemID.ASSEMBLER_MAX_CAPE_BROKEN, 4), + INFERNAL_MAX_CAPE(ItemID.INFERNAL_MAX_CAPE, 4), + INFERNAL_MAX_CAPE_21285(ItemID.INFERNAL_MAX_CAPE_21285, 4), + INFERNAL_MAX_CAPE_BROKEN(ItemID.INFERNAL_MAX_CAPE_BROKEN, 4), + FIRE_MAX_CAPE(ItemID.FIRE_MAX_CAPE, 4), + FIRE_MAX_CAPE_21186(ItemID.FIRE_MAX_CAPE_21186, 4), + FIRE_MAX_CAPE_BROKEN(ItemID.FIRE_MAX_CAPE_BROKEN, 4), + GUTHIX_MAX_CAPE(ItemID.GUTHIX_MAX_CAPE, 4), + IMBUED_GUTHIX_MAX_CAPE(ItemID.IMBUED_GUTHIX_MAX_CAPE, 4), + SARADOMIN_MAX_CAPE(ItemID.SARADOMIN_MAX_CAPE, 4), + IMBUED_SARADOMIN_MAX_CAPE(ItemID.IMBUED_SARADOMIN_MAX_CAPE, 4), + ZAMORAK_MAX_CAPE(ItemID.ZAMORAK_MAX_CAPE, 4), + IMBUED_ZAMORAK_MAX_CAPE(ItemID.IMBUED_ZAMORAK_MAX_CAPE, 4), + ARDOUGNE_CLOAK_2(ItemID.ARDOUGNE_CLOAK_2, 4), + ARDOUGNE_CLOAK_3(ItemID.ARDOUGNE_CLOAK_3, 5), + _3RD_AGE_CLOAK(ItemID._3RD_AGE_CLOAK, 5), + ARDOUGNE_CLOAK_4(ItemID.ARDOUGNE_CLOAK_4, 6), + + // Weapons + ARMADYL_CROSSBOW(ItemID.ARMADYL_CROSSBOW, 1), + BRONZE_MACE(ItemID.BRONZE_MACE, 1), + IRON_MACE(ItemID.IRON_MACE, 1), + WHITE_DAGGER(ItemID.WHITE_DAGGER, 1), + WHITE_SCIMITAR(ItemID.WHITE_SCIMITAR, 1), + WHITE_CLAWS(ItemID.WHITE_CLAWS, 1), + WHITE_SWORD(ItemID.WHITE_SWORD, 1), + WHITE_LONGSWORD(ItemID.WHITE_LONGSWORD, 1), + WHITE_BATTLEAXE(ItemID.WHITE_BATTLEAXE, 1), + WHITE_WARHAMMER(ItemID.WHITE_WARHAMMER, 1), + WHITE_2H_SWORD(ItemID.WHITE_2H_SWORD, 1), + WHITE_HALBERD(ItemID.WHITE_HALBERD, 1), + WHITE_MAGIC_STAFF(ItemID.WHITE_MAGIC_STAFF, 1), + SARADOMIN_SWORD(ItemID.SARADOMIN_SWORD, 2), + SARADOMINS_BLESSED_SWORD(ItemID.SARADOMINS_BLESSED_SWORD, 2), + STEEL_MACE(ItemID.STEEL_MACE, 2), + BLACK_MACE(ItemID.BLACK_MACE, 2), + ZAMORAKIAN_SPEAR(ItemID.ZAMORAKIAN_SPEAR, 2), + ZAMORAKIAN_HASTA(ItemID.ZAMORAKIAN_HASTA, 2), + ADAMANT_MACE(ItemID.ADAMANT_MACE, 3), + ANCIENT_MACE(ItemID.ANCIENT_MACE, 3), + MITHRIL_MACE(ItemID.MITHRIL_MACE, 3), + WHITE_MACE(ItemID.WHITE_MACE, 3), + LUNAR_STAFF(ItemID.LUNAR_STAFF, 3), + RUNE_MACE(ItemID.RUNE_MACE, 4), + ROLLING_PIN(ItemID.ROLLING_PIN, 4), + TWISTED_BOW(ItemID.TWISTED_BOW, 4), + DRAGON_MACE(ItemID.DRAGON_MACE, 5), + WOLFBANE(ItemID.WOLFBANE, 5), + SILVER_SICKLEB(ItemID.SILVER_SICKLE_B, 5), + TOKTZMEJTAL(ItemID.TOKTZMEJTAL, 5), + ANCIENT_CROZIER(ItemID.ANCIENT_CROZIER, 6), + ARMADYL_CROZIER(ItemID.ARMADYL_CROZIER, 6), + BANDOS_CROZIER(ItemID.BANDOS_CROZIER, 6), + GUTHIX_CROZIER(ItemID.GUTHIX_CROZIER, 6), + SARADOMIN_CROZIER(ItemID.SARADOMIN_CROZIER, 6), + ZAMORAK_CROZIER(ItemID.ZAMORAK_CROZIER, 6), + VERACS_FLAIL(ItemID.VERACS_FLAIL, 6), + VERACS_FLAIL_0(ItemID.VERACS_FLAIL_0, 6), + VERACS_FLAIL_25(ItemID.VERACS_FLAIL_25, 6), + VERACS_FLAIL_50(ItemID.VERACS_FLAIL_50, 6), + VERACS_FLAIL_75(ItemID.VERACS_FLAIL_75, 6), + VERACS_FLAIL_100(ItemID.VERACS_FLAIL_100, 6), + VOID_KNIGHT_MACE(ItemID.VOID_KNIGHT_MACE, 6), + VOID_KNIGHT_MACE_BROKEN(ItemID.VOID_KNIGHT_MACE_BROKEN, 6), + BANDOS_GODSWORD(ItemID.BANDOS_GODSWORD, 8), + BANDOS_GODSWORD_OR(ItemID.BANDOS_GODSWORD_OR, 8), + BANDOS_GODSWORD_20782(ItemID.BANDOS_GODSWORD_20782, 8), + BANDOS_GODSWORD_21060(ItemID.BANDOS_GODSWORD_21060, 8), + ARMADYL_GODSWORD(ItemID.ARMADYL_GODSWORD, 8), + ARMADYL_GODSWORD_OR(ItemID.ARMADYL_GODSWORD_OR, 8), + ARMADYL_GODSWORD_20593(ItemID.ARMADYL_GODSWORD_20593, 8), + SARADOMIN_GODSWORD(ItemID.SARADOMIN_GODSWORD, 8), + SARADOMIN_GODSWORD_OR(ItemID.SARADOMIN_GODSWORD_OR, 8), + ZAMORAK_GODSWORD(ItemID.ZAMORAK_GODSWORD, 8), + ZAMORAK_GODSWORD_OR(ItemID.ZAMORAK_GODSWORD_OR, 8), + + // Shields + WHITE_KITESHIELD(ItemID.WHITE_KITESHIELD, 1), + WHITE_SQ_SHIELD(ItemID.WHITE_SQ_SHIELD, 1), + SPIRIT_SHIELD(ItemID.SPIRIT_SHIELD, 1), + FALADOR_SHIELD_1(ItemID.FALADOR_SHIELD_1, 1), + KHAREDSTS_MEMOIRS(ItemID.KHAREDSTS_MEMOIRS, 1), + BLESSED_SPIRIT_SHIELD(ItemID.BLESSED_SPIRIT_SHIELD, 3), + ARCANE_SPIRIT_SHIELD(ItemID.ARCANE_SPIRIT_SHIELD, 3), + SPECTRAL_SPIRIT_SHIELD(ItemID.SPECTRAL_SPIRIT_SHIELD, 3), + ELYSIAN_SPIRIT_SHIELD(ItemID.ELYSIAN_SPIRIT_SHIELD, 3), + ELYSIAN_SPIRIT_SHIELD_19559(ItemID.ELYSIAN_SPIRIT_SHIELD_19559, 3), + FALADOR_SHIELD_2(ItemID.FALADOR_SHIELD_2, 3), + FALADOR_SHIELD_3(ItemID.FALADOR_SHIELD_3, 4), + BROODOO_SHIELD(ItemID.BROODOO_SHIELD, 5), + BROODOO_SHIELD_6257(ItemID.BROODOO_SHIELD_6257, 5), + BROODOO_SHIELD_6279(ItemID.BROODOO_SHIELD_6279, 5), + BROODOO_SHIELD_1(ItemID.BROODOO_SHIELD_1, 5), + BROODOO_SHIELD_1_6255(ItemID.BROODOO_SHIELD_1_6255, 5), + BROODOO_SHIELD_1_6277(ItemID.BROODOO_SHIELD_1_6277, 5), + BROODOO_SHIELD_2(ItemID.BROODOO_SHIELD_2, 5), + BROODOO_SHIELD_2_6253(ItemID.BROODOO_SHIELD_2_6253, 5), + BROODOO_SHIELD_2_6275(ItemID.BROODOO_SHIELD_2_6275, 5), + BROODOO_SHIELD_3(ItemID.BROODOO_SHIELD_3, 5), + BROODOO_SHIELD_3_6251(ItemID.BROODOO_SHIELD_3_6251, 5), + BROODOO_SHIELD_3_6273(ItemID.BROODOO_SHIELD_3_6273, 5), + BROODOO_SHIELD_4(ItemID.BROODOO_SHIELD_4, 5), + BROODOO_SHIELD_4_6249(ItemID.BROODOO_SHIELD_4_6249, 5), + BROODOO_SHIELD_4_6271(ItemID.BROODOO_SHIELD_4_6271, 5), + BROODOO_SHIELD_5(ItemID.BROODOO_SHIELD_5, 5), + BROODOO_SHIELD_5_6247(ItemID.BROODOO_SHIELD_5_6247, 5), + BROODOO_SHIELD_5_6269(ItemID.BROODOO_SHIELD_5_6269, 5), + BROODOO_SHIELD_6(ItemID.BROODOO_SHIELD_6, 5), + BROODOO_SHIELD_6_6245(ItemID.BROODOO_SHIELD_6_6245, 5), + BROODOO_SHIELD_6_6267(ItemID.BROODOO_SHIELD_6_6267, 5), + BROODOO_SHIELD_7(ItemID.BROODOO_SHIELD_7, 5), + BROODOO_SHIELD_7_6243(ItemID.BROODOO_SHIELD_7_6243, 5), + BROODOO_SHIELD_7_6265(ItemID.BROODOO_SHIELD_7_6265, 5), + BROODOO_SHIELD_8(ItemID.BROODOO_SHIELD_8, 5), + BROODOO_SHIELD_8_6241(ItemID.BROODOO_SHIELD_8_6241, 5), + BROODOO_SHIELD_8_6263(ItemID.BROODOO_SHIELD_8_6263, 5), + BROODOO_SHIELD_9(ItemID.BROODOO_SHIELD_9, 5), + BROODOO_SHIELD_9_6239(ItemID.BROODOO_SHIELD_9_6239, 5), + BROODOO_SHIELD_9_6261(ItemID.BROODOO_SHIELD_9_6261, 5), + BROODOO_SHIELD_10(ItemID.BROODOO_SHIELD_10, 5), + BROODOO_SHIELD_10_6237(ItemID.BROODOO_SHIELD_10_6237, 5), + BROODOO_SHIELD_10_6259(ItemID.BROODOO_SHIELD_10_6259, 5), + BOOK_OF_DARKNESS(ItemID.BOOK_OF_DARKNESS, 5), + DAMAGED_BOOK_12611(ItemID.DAMAGED_BOOK_12611, 5), + BOOK_OF_BALANCE(ItemID.BOOK_OF_BALANCE, 5), + DAMAGED_BOOK_3843(ItemID.DAMAGED_BOOK_3843, 5), + BOOK_OF_LAW(ItemID.BOOK_OF_LAW, 5), + DAMAGED_BOOK_12609(ItemID.DAMAGED_BOOK_12609, 5), + BOOK_OF_WAR(ItemID.BOOK_OF_WAR, 5), + DAMAGED_BOOK_12607(ItemID.DAMAGED_BOOK_12607, 5), + HOLY_BOOK(ItemID.HOLY_BOOK, 5), + DAMAGED_BOOK(ItemID.DAMAGED_BOOK, 5), + UNHOLY_BOOK(ItemID.UNHOLY_BOOK, 5), + DAMAGED_BOOK_3841(ItemID.DAMAGED_BOOK_3841, 5), + FALADOR_SHIELD_4(ItemID.FALADOR_SHIELD_4, 5); + + private static final Map prayerBonuses = new HashMap<>(); + + private final int itemId; + private final int prayerBonus; + + static + { + for (PrayerItems item : values()) + { + prayerBonuses.put(item.getItemId(), item.getPrayerBonus()); + } + } + + public static int getItemPrayerBonus(int itemId) + { + Integer value = prayerBonuses.get(itemId); + return value == null ? 0 : value; + } +} 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 23f902a5b4..44eab5c7d0 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 @@ -29,9 +29,13 @@ import com.google.common.eventbus.Subscribe; import com.google.inject.Provides; import javax.inject.Inject; import net.runelite.api.Client; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; import net.runelite.api.Prayer; import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameTick; +import net.runelite.api.events.ItemContainerChanged; import net.runelite.client.config.ConfigManager; import net.runelite.client.game.SpriteManager; import net.runelite.client.plugins.Plugin; @@ -59,7 +63,10 @@ public class PrayerPlugin extends Plugin private OverlayManager overlayManager; @Inject - private PrayerFlickOverlay overlay; + private PrayerFlickOverlay flickOverlay; + + @Inject + private PrayerDoseOverlay doseOverlay; @Inject private PrayerConfig config; @@ -73,13 +80,15 @@ public class PrayerPlugin extends Plugin @Override protected void startUp() { - overlayManager.add(overlay); + overlayManager.add(flickOverlay); + overlayManager.add(doseOverlay); } @Override protected void shutDown() { - overlayManager.remove(overlay); + overlayManager.remove(flickOverlay); + overlayManager.remove(doseOverlay); removeIndicators(); } @@ -99,12 +108,43 @@ public class PrayerPlugin extends Plugin } } + @Subscribe + public void onItemContainerChanged(final ItemContainerChanged event) + { + final ItemContainer container = event.getItemContainer(); + final ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY); + final ItemContainer equipment = client.getItemContainer(InventoryID.EQUIPMENT); + + if (container == inventory || container == equipment) + { + doseOverlay.setHasHolyWrench(false); + doseOverlay.setHasPrayerPotion(false); + doseOverlay.setHasRestorePotion(false); + + if (inventory != null) + { + checkContainerForPrayer(inventory.getItems()); + } + + if (equipment != null) + { + doseOverlay.setPrayerBonus(checkContainerForPrayer(equipment.getItems())); + } + + } + } + @Subscribe public void onGameTick(GameTick tick) { if (config.prayerFlickHelper()) { - overlay.onTick(); + flickOverlay.onTick(); + } + + if (config.showPrayerDoseIndicator()) + { + doseOverlay.onTick(); } if (!config.prayerIndicator()) @@ -134,12 +174,53 @@ public class PrayerPlugin extends Plugin } else if (prayerCounter[ord] != null) { - infoBoxManager.removeInfoBox(prayerCounter[ord]); - prayerCounter[ord] = null; + infoBoxManager.removeInfoBox(prayerCounter[ord]); + prayerCounter[ord] = null; } } } + private int checkContainerForPrayer(Item[] items) + { + if (items == null) + { + return 0; + } + + int total = 0; + + for (Item item : items) + { + if (item == null) + { + continue; + } + + final PrayerRestoreType type = PrayerRestoreType.getType(item.getId()); + + if (type != null) + { + switch (type) + { + case PRAYERPOT: + doseOverlay.setHasPrayerPotion(true); + break; + case HOLYWRENCH: + doseOverlay.setHasHolyWrench(true); + break; + case RESTOREPOT: + doseOverlay.setHasRestorePotion(true); + break; + } + } + + int bonus = PrayerItems.getItemPrayerBonus(item.getId()); + total += bonus; + } + + return total; + } + private void removeIndicators() { infoBoxManager.removeIf(entry -> entry instanceof PrayerCounter); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerRestoreType.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerRestoreType.java new file mode 100644 index 0000000000..b8475f60e7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerRestoreType.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * 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.prayer; + +import java.util.HashMap; +import java.util.Map; +import net.runelite.api.ItemID; + +enum PrayerRestoreType +{ + RESTOREPOT(ItemID.SUPER_RESTORE4, ItemID.SUPER_RESTORE3, ItemID.SUPER_RESTORE2, ItemID.SUPER_RESTORE1), + PRAYERPOT(ItemID.PRAYER_POTION4, ItemID.PRAYER_POTION3, ItemID.PRAYER_POTION2, ItemID.PRAYER_POTION1), + HOLYWRENCH(ItemID.PRAYER_CAPE, ItemID.PRAYER_CAPET, ItemID.PRAYER_CAPE_10643, ItemID.MAX_CAPE, ItemID.MAX_CAPE_13282, + ItemID.MAX_CAPE_13342, ItemID.HOLY_WRENCH, ItemID.RING_OF_THE_GODS, ItemID.RING_OF_THE_GODS_I); + + private static final Map prayerRestores = new HashMap<>(); + + private final int[] items; + + PrayerRestoreType(int... items) + { + this.items = items; + } + + static + { + for (PrayerRestoreType prayerRestoreType : values()) + { + for (int itemId : prayerRestoreType.items) + { + prayerRestores.put(itemId, prayerRestoreType); + } + } + } + + static PrayerRestoreType getType(final int itemId) + { + return prayerRestores.get(itemId); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/util/SwingUtil.java b/runelite-client/src/main/java/net/runelite/client/util/SwingUtil.java index 6a4e1a0d65..fa626cf651 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/SwingUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/util/SwingUtil.java @@ -372,4 +372,27 @@ public class SwingUtil { return SubstanceCoreUtilities.getTitlePaneComponent(frame) != null; } + + /** + * Linearly interpolates between colors a and b by t. + * @param a first color + * @param b second color + * @param t factor + * @return interpolated color + */ + public static Color colorLerp(Color a, Color b, double t) + { + final double r1 = a.getRed(); + final double r2 = b.getRed(); + final double g1 = a.getGreen(); + final double g2 = b.getGreen(); + final double b1 = a.getBlue(); + final double b2 = b.getBlue(); + + return new Color( + (int) Math.round(r1 + (t * (r2 - r1))), + (int) Math.round(g1 + (t * (g2 - g1))), + (int) Math.round(b1 + (t * (b2 - b1))) + ); + } }