diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsConfig.java index 573e561e2d..f8d0fed78f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsConfig.java @@ -27,6 +27,7 @@ package net.runelite.client.plugins.statusbars; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; +import net.runelite.client.plugins.statusbars.config.BarMode; @ConfigGroup("statusbars") public interface StatusBarsConfig extends Config @@ -34,8 +35,8 @@ public interface StatusBarsConfig extends Config @ConfigItem( position = 1, keyName = "enableCounter", - name = "Show hitpoints & prayer counter", - description = "Shows current amount of hitpoints & prayer on the status bars" + name = "Show counters", + description = "Shows currentValue value of the status on the bar" ) default boolean enableCounter() { @@ -45,7 +46,7 @@ public interface StatusBarsConfig extends Config @ConfigItem( position = 2, keyName = "enableSkillIcon", - name = "Show hitpoints & prayer icons", + name = "Show icons", description = "Adds skill icons at the top of the bars." ) default boolean enableSkillIcon() @@ -56,8 +57,8 @@ public interface StatusBarsConfig extends Config @ConfigItem( position = 3, keyName = "enableRestorationBars", - name = "Show amount of hitpoints and prayer restored", - description = "Visually shows how much a food or prayer will heal/restore you on the bars." + name = "Show restores", + description = "Visually shows how much will be restored to your status bar." ) default boolean enableRestorationBars() { @@ -65,7 +66,29 @@ public interface StatusBarsConfig extends Config } @ConfigItem( - position = 4, + position = 4, + keyName = "leftBarMode", + name = "Left Status Bar", + description = "Configures the left status bar" + ) + default BarMode leftBarMode() + { + return BarMode.HITPOINTS; + } + + @ConfigItem( + position = 5, + keyName = "rightBarMode", + name = "Right Status Bar", + description = "Configures the right status bar" + ) + default BarMode rightBarMode() + { + return BarMode.PRAYER; + } + + @ConfigItem( + position = 6, keyName = "toggleRestorationBars", name = "Toggle to hide when not in combat", description = "Visually hides the Status Bars when player is out of combat." @@ -76,7 +99,7 @@ public interface StatusBarsConfig extends Config } @ConfigItem( - position = 5, + position = 7, keyName = "hideStatusBarDelay", name = "Delay (seconds)", description = "Number of seconds after combat to hide the status bars." diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsOverlay.java index e92251bec0..4e73ba40b7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsOverlay.java @@ -24,78 +24,47 @@ */ package net.runelite.client.plugins.statusbars; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Image; -import javax.inject.Inject; +import com.google.common.base.Strings; +import com.google.common.primitives.Ints; import net.runelite.api.Client; import net.runelite.api.MenuEntry; import net.runelite.api.Point; -import net.runelite.api.Skill; -import net.runelite.api.VarPlayer; -import net.runelite.api.Varbits; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; -import net.runelite.client.game.SkillIconManager; import net.runelite.client.plugins.itemstats.Effect; import net.runelite.client.plugins.itemstats.ItemStatChangesService; import net.runelite.client.plugins.itemstats.StatChange; import net.runelite.client.plugins.itemstats.StatsChanges; -import net.runelite.client.ui.FontManager; +import net.runelite.client.plugins.statusbars.renderer.BarRenderer; 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.components.TextComponent; -import net.runelite.client.util.ImageUtil; -class StatusBarsOverlay extends Overlay +import javax.inject.Inject; +import java.awt.Dimension; +import java.awt.Graphics2D; + +public class StatusBarsOverlay extends Overlay { - private static final Color PRAYER_COLOR = new Color(50, 200, 200, 175); - private static final Color QUICK_PRAYER_COLOR = new Color(57, 255, 186, 225); - private static final Color BACKGROUND = new Color(0, 0, 0, 150); - private static final Color HEALTH_COLOR = new Color(225, 35, 0, 125); - private static final Color POISONED_COLOR = new Color(0, 145, 0, 150); - private static final Color VENOMED_COLOR = new Color(0, 65, 0, 150); - private static final Color HEAL_COLOR = new Color(255, 112, 6, 150); - private static final Color PRAYER_HEAL_COLOR = new Color(57, 255, 186, 75); - private static final Color OVERHEAL_COLOR = new Color(216, 255, 139, 150); private static final int HEIGHT = 252; private static final int RESIZED_BOTTOM_HEIGHT = 272; - private static final int WIDTH = 20; - private static final int PADDING = 1; - private static final int IMAGE_SIZE = 17; - private static final int HEALTH_LOCATION_X = 0; - private static final int PRAYER_LOCATION_X = 1; private static final int RESIZED_BOTTOM_OFFSET_Y = 12; private static final int RESIZED_BOTTOM_OFFSET_X = 10; - private static final int OVERHEAL_OFFSET = 2; - private static final int HEAL_OFFSET = 3; - private static final int ICON_AND_COUNTER_OFFSET_X = 1; - private static final int ICON_AND_COUNTER_OFFSET_Y = 21; - private static final int SKILL_ICON_HEIGHT = 35; - private static final int COUNTER_ICON_HEIGHT = 18; - private static final int OFFSET = 2; private final Client client; + private final StatusBarsPlugin plugin; private final StatusBarsConfig config; - private final SkillIconManager skillIconManager; - private final TextComponent textComponent = new TextComponent(); private final ItemStatChangesService itemStatService; - private final Image prayerImage; - @Inject - private StatusBarsOverlay(Client client, StatusBarsConfig config, SkillIconManager skillIconManager, ItemStatChangesService itemstatservice) + private StatusBarsOverlay(Client client, StatusBarsPlugin plugin, StatusBarsConfig config, ItemStatChangesService itemstatservice) { setPosition(OverlayPosition.DYNAMIC); setLayer(OverlayLayer.ABOVE_WIDGETS); this.client = client; + this.plugin = plugin; this.config = config; - this.skillIconManager = skillIconManager; this.itemStatService = itemstatservice; - - prayerImage = ImageUtil.resizeImage(skillIconManager.getSkillImage(Skill.PRAYER, true), IMAGE_SIZE, IMAGE_SIZE); } @Override @@ -129,194 +98,86 @@ class StatusBarsOverlay extends Overlay final Point offsetLeft = curViewport.getOffsetLeft(); final Point offsetRight = curViewport.getOffsetRight(); final Point location = curWidget.getCanvasLocation(); - final int height, offsetHealthX, offsetHealthY, offsetPrayerX, offsetPrayerY; + final int height, offsetLeftBarX, offsetLeftBarY, offsetRightBarX, offsetRightBarY; if (curViewport == Viewport.RESIZED_BOTTOM) { height = RESIZED_BOTTOM_HEIGHT; - offsetHealthX = (location.getX() + RESIZED_BOTTOM_OFFSET_X - offsetLeft.getX()); - offsetHealthY = (location.getY() - RESIZED_BOTTOM_OFFSET_Y - offsetRight.getY()); - offsetPrayerX = (location.getX() + RESIZED_BOTTOM_OFFSET_X - offsetRight.getX()); - offsetPrayerY = (location.getY() - RESIZED_BOTTOM_OFFSET_Y - offsetRight.getY()); + offsetLeftBarX = (location.getX() + RESIZED_BOTTOM_OFFSET_X - offsetLeft.getX()); + offsetLeftBarY = (location.getY() - RESIZED_BOTTOM_OFFSET_Y - offsetRight.getY()); + offsetRightBarX = (location.getX() + RESIZED_BOTTOM_OFFSET_X - offsetRight.getX()); + offsetRightBarY = (location.getY() - RESIZED_BOTTOM_OFFSET_Y - offsetRight.getY()); } else { height = HEIGHT; - offsetHealthX = (location.getX() - offsetLeft.getX()); - offsetHealthY = (location.getY() - offsetLeft.getY()); - offsetPrayerX = (location.getX() - offsetRight.getX()) + curWidget.getWidth(); - offsetPrayerY = (location.getY() - offsetRight.getY()); + offsetLeftBarX = (location.getX() - offsetLeft.getX()); + offsetLeftBarY = (location.getY() - offsetLeft.getY()); + offsetRightBarX = (location.getX() - offsetRight.getX()) + curWidget.getWidth(); + offsetRightBarY = (location.getY() - offsetRight.getY()); } - final int poisonState = client.getVar(VarPlayer.IS_POISONED); - final Color healthBar; + BarRenderer left = plugin.getBarRenderers().get(config.leftBarMode()); + BarRenderer right = plugin.getBarRenderers().get(config.rightBarMode()); - if (poisonState >= 1000000) + if (left != null) { - healthBar = VENOMED_COLOR; - } - else if (poisonState > 0) - { - healthBar = POISONED_COLOR; - } - else - { - healthBar = HEALTH_COLOR; + left.draw(client, this, g, offsetLeftBarX, offsetLeftBarY, height); } - final int maxHealth = client.getRealSkillLevel(Skill.HITPOINTS); - final int maxPrayer = client.getRealSkillLevel(Skill.PRAYER); - final int currentHealth = client.getBoostedSkillLevel(Skill.HITPOINTS); - final int currentPrayer = client.getBoostedSkillLevel(Skill.PRAYER); - final int quickPrayerState = client.getVar(Varbits.QUICK_PRAYER); - final Color prayerBar = quickPrayerState == 1 ? QUICK_PRAYER_COLOR : PRAYER_COLOR; - - renderBar(g, offsetHealthX, offsetHealthY, - maxHealth, currentHealth, height, healthBar); - - renderBar(g, offsetPrayerX, offsetPrayerY, - maxPrayer, currentPrayer, height, prayerBar); - - if (config.enableRestorationBars()) + if (right != null) { - final MenuEntry[] menu = client.getMenuEntries(); - final int menuSize = menu.length; - final MenuEntry entry = menuSize > 0 ? menu[menuSize - 1] : null; - int prayerHealValue = 0; - int foodHealValue = 0; - if (entry != null && entry.getParam1() == WidgetInfo.INVENTORY.getId()) - { - final Effect change = itemStatService.getItemStatChanges(entry.getIdentifier()); - - if (change != null) - { - final StatsChanges statsChanges = change.calculate(client); - - for (final StatChange c : statsChanges.getStatChanges()) - { - final int theoreticalBoost = c.getTheoretical(); - - if (c.getStat().getName().equals(Skill.HITPOINTS.getName())) - { - foodHealValue = theoreticalBoost; - } - - if (c.getStat().getName().equals(Skill.PRAYER.getName())) - { - prayerHealValue = theoreticalBoost; - } - - if (foodHealValue != 0 && prayerHealValue != 0) - { - break; - } - } - } - } - - renderHealingBar(g, offsetHealthX, offsetHealthY, - maxHealth, currentHealth, height, - foodHealValue, HEAL_COLOR); - - renderHealingBar(g, offsetPrayerX, offsetPrayerY, - maxPrayer, currentPrayer, height, - prayerHealValue, PRAYER_HEAL_COLOR); - } - - if (config.enableSkillIcon() || config.enableCounter()) - { - final Image healthImage = skillIconManager.getSkillImage(Skill.HITPOINTS, true); - final int counterHealth = client.getBoostedSkillLevel(Skill.HITPOINTS); - final int counterPrayer = client.getBoostedSkillLevel(Skill.PRAYER); - final String counterHealthText = Integer.toString(counterHealth); - final String counterPrayerText = Integer.toString(counterPrayer); - - renderIconsAndCounters(g, offsetPrayerX, offsetPrayerY, prayerImage, counterPrayerText, PRAYER_LOCATION_X); - renderIconsAndCounters(g, offsetHealthX, offsetHealthY, healthImage, counterHealthText, HEALTH_LOCATION_X); + right.draw(client, this, g, offsetRightBarX, offsetRightBarY, height); } return null; } - private static void renderBar(Graphics2D graphics, int x, int y, int max, int current, int height, Color filled) + public int getRestoreValue(String skill) { - graphics.setColor(BACKGROUND); - graphics.drawRect(x, y, WIDTH - PADDING, height - PADDING); - graphics.fillRect(x, y, WIDTH, height); + final MenuEntry[] menu = client.getMenuEntries(); + final int menuSize = menu.length; + final MenuEntry entry = menuSize > 0 ? menu[menuSize - 1] : null; + int restoreValue = 0; - final int filledHeight = getBarHeight(max, current, height); - graphics.setColor(filled); - graphics.fillRect(x + PADDING, - y + PADDING + (height - filledHeight), - WIDTH - PADDING * OFFSET, - filledHeight - PADDING * OFFSET); + if (entry != null && entry.getParam1() == WidgetInfo.INVENTORY.getId()) + { + final Effect change = itemStatService.getItemStatChanges(entry.getIdentifier()); + + if (change != null) + { + final StatsChanges statsChanges = change.calculate(client); + + for (final StatChange c : statsChanges.getStatChanges()) + { + //final String strVar = c.getTheoretical(); this was erroring + final String strVar = String.valueOf(c.getTheoretical()); // not sure if wrapping in string.valueof will work? + + if (Strings.isNullOrEmpty(strVar)) + { + continue; + } + + final Integer value = Ints.tryParse(strVar.startsWith("+") ? strVar.substring(1) : strVar); + + if (value == null) + { + continue; + } + + if (c.getStat().getName().equals(skill)) + { + restoreValue = value; + } + + if (restoreValue != 0) + { + break; + } + } + } + } + + return restoreValue; } - - private static void renderHealingBar(Graphics2D graphics, int x, int y, int max, int current, int height, int heal, Color color) - { - if (heal <= 0) - { - return; - } - - final int filledCurrentHeight = getBarHeight(max, current, height); - int filledHeight = getBarHeight(max, heal, height); - graphics.setColor(color); - - if (filledHeight + filledCurrentHeight > height) - { - final int overHeal = filledHeight + filledCurrentHeight - height; - filledHeight = filledHeight - overHeal + OVERHEAL_OFFSET; - graphics.setColor(OVERHEAL_COLOR); - graphics.fillRect(x + PADDING, - y - filledCurrentHeight + (height - filledHeight) + HEAL_OFFSET, - WIDTH - PADDING * OVERHEAL_OFFSET, - filledHeight - PADDING * OVERHEAL_OFFSET); - } - else - { - graphics.fillRect(x + PADDING, - y - OVERHEAL_OFFSET - filledCurrentHeight + (height - filledHeight) + HEAL_OFFSET, - WIDTH - PADDING * OVERHEAL_OFFSET, - filledHeight + OVERHEAL_OFFSET - PADDING * OVERHEAL_OFFSET); - } - } - - private static int getBarHeight(int base, int current, int size) - { - final double ratio = (double) current / base; - - if (ratio >= 1) - { - return size; - } - - return (int) Math.round(ratio * size); - } - - private void renderIconsAndCounters(Graphics2D graphics, int x, int y, Image image, String counterText, int counterPadding) - { - final int widthOfCounter = graphics.getFontMetrics().stringWidth(counterText); - final int centerText = (WIDTH - PADDING) / 2 - (widthOfCounter / 2); - - if (config.enableCounter()) - { - graphics.setFont(FontManager.getRunescapeSmallFont()); - textComponent.setColor(Color.WHITE); - textComponent.setText(counterText); - textComponent.setPosition(new java.awt.Point(x + centerText + counterPadding, y + COUNTER_ICON_HEIGHT)); - } - else - { - textComponent.setText(""); - } - - if (config.enableSkillIcon()) - { - graphics.drawImage(image, x + ICON_AND_COUNTER_OFFSET_X + PADDING, y + ICON_AND_COUNTER_OFFSET_Y - image.getWidth(null), null); - textComponent.setPosition(new java.awt.Point(x + centerText + counterPadding, y + SKILL_ICON_HEIGHT)); - } - - textComponent.render(graphics); - } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsPlugin.java index 66f05b81b3..221d570224 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsPlugin.java @@ -24,7 +24,11 @@ */ package net.runelite.client.plugins.statusbars; +import javax.inject.Inject; + +import com.google.common.collect.Maps; import com.google.inject.Provides; +import lombok.Getter; import java.time.Duration; import java.time.Instant; import java.util.Arrays; @@ -43,11 +47,20 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDependency; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.itemstats.ItemStatPlugin; +import net.runelite.client.plugins.statusbars.config.BarMode; +import net.runelite.client.plugins.statusbars.renderer.BarRenderer; +import net.runelite.client.plugins.statusbars.renderer.EnergyRenderer; +import net.runelite.client.plugins.statusbars.renderer.HitPointsRenderer; +import net.runelite.client.plugins.statusbars.renderer.PrayerRenderer; +import net.runelite.client.plugins.statusbars.renderer.SpecialAttackRenderer; import net.runelite.client.ui.overlay.OverlayManager; +import java.util.HashMap; +import java.util.Map; + @PluginDescriptor( name = "Status Bars", - description = "Draws status bars next to players inventory showing current HP & Prayer and healing amounts", + description = "Draws status bars next to players inventory showing currentValue and restore amounts", enabledByDefault = false ) @PluginDependency(ItemStatPlugin.class) @@ -59,6 +72,21 @@ public class StatusBarsPlugin extends Plugin @Inject private OverlayManager overlayManager; + @Inject + private HitPointsRenderer hitPointsRenderer; + + @Inject + private PrayerRenderer prayerRenderer; + + @Inject + private EnergyRenderer energyRenderer; + + @Inject + private SpecialAttackRenderer specialAttackRenderer; + + @Getter + private final Map barRenderers = Maps.newEnumMap(BarMode.class); + @Inject private Client client; @@ -71,6 +99,12 @@ public class StatusBarsPlugin extends Plugin @Override protected void startUp() throws Exception { + overlayManager.add(overlay); + barRenderers.put(BarMode.DISABLED, null); + barRenderers.put(BarMode.HITPOINTS, hitPointsRenderer); + barRenderers.put(BarMode.PRAYER, prayerRenderer); + barRenderers.put(BarMode.RUN_ENERGY, energyRenderer); + barRenderers.put(BarMode.SPECIAL_ATTACK, specialAttackRenderer); } void updateLastCombatAction() @@ -122,6 +156,7 @@ public class StatusBarsPlugin extends Plugin protected void shutDown() throws Exception { overlayManager.remove(overlay); + barRenderers.clear(); } @Provides diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/config/BarMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/config/BarMode.java new file mode 100644 index 0000000000..7da3d0c308 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/config/BarMode.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018, Lotto + * 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.statusbars.config; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum BarMode +{ + DISABLED("Disabled"), + HITPOINTS("Hitpoints"), + PRAYER("Prayer"), + RUN_ENERGY("Run Energy"), + SPECIAL_ATTACK("Special Attack"); + + private final String name; + + @Override + public String toString() + { + return name; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/renderer/BarRenderer.java b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/renderer/BarRenderer.java new file mode 100644 index 0000000000..21ed8fd96b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/renderer/BarRenderer.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2018, Rheon + * 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 HOLDER 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.statusbars.renderer; + +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import net.runelite.api.Client; +import net.runelite.client.plugins.statusbars.StatusBarsConfig; +import net.runelite.client.plugins.statusbars.StatusBarsOverlay; +import net.runelite.client.ui.FontManager; +import net.runelite.client.ui.overlay.components.TextComponent; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Point; + +@RequiredArgsConstructor(access = AccessLevel.PROTECTED) +public abstract class BarRenderer +{ + private static final TextComponent TEXT = new TextComponent(); + private static final Color COLOR_BAR_BG = new Color(0, 0, 0, 150); + private static final Color COLOR_OVERHEAL = new Color(216, 255, 139, 150); + private static final int BAR_WIDTH = 20; + private static final int COUNTER_ICON_HEIGHT = 18; + private static final int SKILL_ICON_HEIGHT = 35; + private static final int PADDING = 1; + private static final int OVERHEAL_OFFSET = 2; + private static final int HEAL_OFFSET = 3; + private static final int ICON_AND_COUNTER_OFFSET_X = 1; + private static final int ICON_AND_COUNTER_OFFSET_Y = 21; + private static final int OFFSET = 2; + + protected final StatusBarsConfig config; + protected int maximumValue; + protected int currentValue; + protected int restore; + protected Color standardColor; + protected Color restoreColor; + protected Image icon; + + protected abstract void update(Client client, StatusBarsOverlay overlay); + + private void renderBar(Graphics2D graphics, int x, int y, int height) + { + graphics.setColor(COLOR_BAR_BG); + graphics.drawRect(x, y, BAR_WIDTH - PADDING, height - PADDING); + graphics.fillRect(x, y, BAR_WIDTH, height); + + final int filledHeight = getBarHeight(maximumValue, currentValue, height); + graphics.setColor(standardColor); + graphics.fillRect(x + PADDING, + y + PADDING + (height - filledHeight), + BAR_WIDTH - PADDING * OFFSET, + filledHeight - PADDING * OFFSET); + } + + private void renderIconsAndCounters(Graphics2D graphics, int x, int y) + { + final String counterText = Integer.toString(currentValue); + final int widthOfCounter = graphics.getFontMetrics().stringWidth(counterText); + final int centerText = (BAR_WIDTH - PADDING) / 2 - (widthOfCounter / 2); + + if (config.enableCounter()) + { + graphics.setFont(FontManager.getRunescapeSmallFont()); + TEXT.setText(counterText); + TEXT.setPosition(new Point(x + centerText + 1, y + COUNTER_ICON_HEIGHT)); + } + else + { + TEXT.setText(""); + } + + if (config.enableSkillIcon()) + { + graphics.drawImage(icon, x + ICON_AND_COUNTER_OFFSET_X + PADDING, y + ICON_AND_COUNTER_OFFSET_Y - icon.getWidth(null), null); + TEXT.setPosition(new Point(x + centerText + 1, y + SKILL_ICON_HEIGHT)); + } + + TEXT.render(graphics); + } + + private void renderRestore(Graphics2D graphics, int x, int y, int height) + { + if (restore <= 0) + { + return; + } + + final int filledCurrentHeight = getBarHeight(maximumValue, currentValue, height); + int filledHeight = getBarHeight(maximumValue, restore, height); + graphics.setColor(restoreColor); + + if (filledHeight + filledCurrentHeight > height) + { + final int overHeal = filledHeight + filledCurrentHeight - height; + filledHeight = filledHeight - overHeal + OVERHEAL_OFFSET; + graphics.setColor(COLOR_OVERHEAL); + graphics.fillRect(x + PADDING, + y - filledCurrentHeight + (height - filledHeight) + HEAL_OFFSET, + BAR_WIDTH - PADDING * OVERHEAL_OFFSET, + filledHeight - PADDING * OVERHEAL_OFFSET); + } + else + { + graphics.fillRect(x + PADDING, + y - OVERHEAL_OFFSET - filledCurrentHeight + (height - filledHeight) + HEAL_OFFSET, + BAR_WIDTH - PADDING * OVERHEAL_OFFSET, + filledHeight + OVERHEAL_OFFSET - PADDING * OVERHEAL_OFFSET); + } + } + + private static int getBarHeight(int base, int current, int size) + { + final double ratio = (double) current / base; + + if (ratio >= 1) + { + return size; + } + + return (int) Math.round(ratio * size); + } + + public void draw(Client client, StatusBarsOverlay overlay, Graphics2D graphics, int x, int y, int height) + { + update(client, overlay); + renderBar(graphics, x, y, height); + if (config.enableRestorationBars()) + renderRestore(graphics, x, y, height); + if (config.enableSkillIcon() || config.enableCounter()) + renderIconsAndCounters(graphics, x, y); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/renderer/EnergyRenderer.java b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/renderer/EnergyRenderer.java new file mode 100644 index 0000000000..127aa6b601 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/renderer/EnergyRenderer.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018, Rheon + * 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 HOLDER 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.statusbars.renderer; + +import net.runelite.api.Client; +import net.runelite.api.SpriteID; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.plugins.statusbars.StatusBarsConfig; +import net.runelite.client.plugins.statusbars.StatusBarsOverlay; + +import javax.inject.Inject; +import java.awt.Color; + +public class EnergyRenderer extends BarRenderer +{ + private final SpriteManager spriteManager; + + @Inject + public EnergyRenderer(StatusBarsConfig config, SpriteManager spriteManager) + { + super(config); + maximumValue = 100; + this.spriteManager = spriteManager; + standardColor = new Color(199, 174, 0, 220); + restoreColor = new Color(199, 118, 0, 218); + } + + @Override + protected void update(Client client, StatusBarsOverlay overlay) + { + icon = spriteManager.getSprite(SpriteID.MINIMAP_ORB_RUN_ICON, 0); + currentValue = client.getEnergy(); + restore = overlay.getRestoreValue("Run Energy"); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/renderer/HitPointsRenderer.java b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/renderer/HitPointsRenderer.java new file mode 100644 index 0000000000..68e1c29548 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/renderer/HitPointsRenderer.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2018, Rheon + * 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 HOLDER 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.statusbars.renderer; + +import net.runelite.api.Client; +import net.runelite.api.Skill; +import net.runelite.api.VarPlayer; +import net.runelite.client.game.SkillIconManager; +import net.runelite.client.plugins.statusbars.StatusBarsConfig; +import net.runelite.client.plugins.statusbars.StatusBarsOverlay; + +import javax.inject.Inject; +import java.awt.Color; + +public class HitPointsRenderer extends BarRenderer +{ + private static final Color COLOR_STANDARD = new Color(225, 35, 0, 125); + private static final Color COLOR_POISON = new Color(0, 145, 0, 150); + private static final Color COLOR_VENOM = new Color(0, 65, 0, 150); + + @Inject + public HitPointsRenderer(StatusBarsConfig config, SkillIconManager iconManager) + { + super(config); + icon = iconManager.getSkillImage(Skill.HITPOINTS, true); + restoreColor = new Color(255, 112, 6, 150); + } + + @Override + protected void update(Client client, StatusBarsOverlay overlay) + { + maximumValue = client.getRealSkillLevel(Skill.HITPOINTS); + currentValue = client.getBoostedSkillLevel(Skill.HITPOINTS); + restore = overlay.getRestoreValue(Skill.HITPOINTS.getName()); + + final int poisonState = client.getVar(VarPlayer.IS_POISONED); + + if (poisonState > 0 && poisonState < 50) + { + standardColor = COLOR_POISON; + } + else if (poisonState >= 1000000) + { + standardColor = COLOR_VENOM; + } + else + { + standardColor = COLOR_STANDARD; + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/renderer/PrayerRenderer.java b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/renderer/PrayerRenderer.java new file mode 100644 index 0000000000..76ed6fadca --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/renderer/PrayerRenderer.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018, Rheon + * 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 HOLDER 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.statusbars.renderer; + +import net.runelite.api.Client; +import net.runelite.api.Skill; +import net.runelite.api.Varbits; +import net.runelite.client.game.SkillIconManager; +import net.runelite.client.plugins.statusbars.StatusBarsConfig; +import net.runelite.client.plugins.statusbars.StatusBarsOverlay; +import net.runelite.client.util.ImageUtil; + +import javax.inject.Inject; +import java.awt.Color; + +public class PrayerRenderer extends BarRenderer +{ + private static final Color COLOR_STANDARD = new Color(50, 200, 200, 175); + private static final Color COLOR_ACTIVE = new Color(57, 255, 186, 225); + private static final int SIZE = 17; + + @Inject + public PrayerRenderer(StatusBarsConfig config, SkillIconManager iconManager) + { + super(config); + icon = ImageUtil.resizeImage(iconManager.getSkillImage(Skill.PRAYER, true), SIZE, SIZE); + restoreColor = new Color(57, 255, 186, 75); + } + + @Override + protected void update(Client client, StatusBarsOverlay overlay) + { + maximumValue = client.getRealSkillLevel(Skill.PRAYER); + currentValue = client.getBoostedSkillLevel(Skill.PRAYER); + standardColor = client.getVar(Varbits.QUICK_PRAYER) == 1 ? COLOR_ACTIVE : COLOR_STANDARD; + restore = overlay.getRestoreValue(Skill.PRAYER.getName()); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/renderer/SpecialAttackRenderer.java b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/renderer/SpecialAttackRenderer.java new file mode 100644 index 0000000000..a2f43f1c2e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/statusbars/renderer/SpecialAttackRenderer.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018, Rheon + * 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 HOLDER 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.statusbars.renderer; + +import net.runelite.api.Client; +import net.runelite.api.SpriteID; +import net.runelite.api.VarPlayer; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.plugins.statusbars.StatusBarsConfig; +import net.runelite.client.plugins.statusbars.StatusBarsOverlay; + +import javax.inject.Inject; +import java.awt.Color; + +public class SpecialAttackRenderer extends BarRenderer +{ + private final SpriteManager spriteManager; + + @Inject + public SpecialAttackRenderer(StatusBarsConfig config, SpriteManager spriteManager) + { + super(config); + maximumValue = 100; + this.spriteManager = spriteManager; + standardColor = restoreColor = new Color(3, 153, 0, 195); + } + + @Override + protected void update(Client client, StatusBarsOverlay overlay) + { + icon = spriteManager.getSprite(SpriteID.MINIMAP_ORB_SPECIAL_ICON, 0); + currentValue = client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT) / 10; + restore = 0; + } +}