diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 2b7d3aa844..47a969ccb4 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -1480,6 +1480,14 @@ public interface Client extends GameEngine */ NodeCache getWidgetSpriteCache(); + /** + * Overrides health bar sprites with the sprites from the specified override. + * Pass in {@code null} to revert the health bars back to their default. + * + * @param override the health bar override + */ + void setHealthBarOverride(HealthBarOverride override); + /** * Gets the current server tick count. * diff --git a/runelite-api/src/main/java/net/runelite/api/HealthBarOverride.java b/runelite-api/src/main/java/net/runelite/api/HealthBarOverride.java new file mode 100644 index 0000000000..b53b480518 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/HealthBarOverride.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019, 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 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.api; + +import lombok.Data; + +@Data +public class HealthBarOverride +{ + public final SpritePixels frontSprite; + public final SpritePixels backSprite; + public final SpritePixels frontSpriteLarge; + public final SpritePixels backSpriteLarge; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/InterfaceStylesConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/InterfaceStylesConfig.java index e86fe0d2bb..281361eebc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/InterfaceStylesConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/InterfaceStylesConfig.java @@ -42,4 +42,14 @@ public interface InterfaceStylesConfig extends Config { return Skin.AROUND_2010; } + + @ConfigItem( + keyName = "hdHealthBars", + name = "High Detail health bars", + description = "Replaces health bars with the RuneScape High Detail mode design" + ) + default boolean hdHealthBars() + { + return false; + } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/InterfaceStylesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/InterfaceStylesPlugin.java index 27d955c257..226b8da617 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/InterfaceStylesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/interfacestyles/InterfaceStylesPlugin.java @@ -31,6 +31,7 @@ import java.awt.image.BufferedImage; import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; +import net.runelite.api.HealthBarOverride; import net.runelite.api.SpriteID; import net.runelite.api.SpritePixels; import net.runelite.api.events.ConfigChanged; @@ -85,6 +86,7 @@ public class InterfaceStylesPlugin extends Plugin { restoreWidgetDimensions(); removeGameframe(); + client.setHealthBarOverride(null); }); } @@ -110,6 +112,7 @@ public class InterfaceStylesPlugin extends Plugin overrideWidgetSprites(); restoreWidgetDimensions(); adjustWidgetDimensions(); + overrideHealthBars(); } private void overrideSprites() @@ -229,6 +232,27 @@ public class InterfaceStylesPlugin extends Plugin } } + private void overrideHealthBars() + { + if (config.hdHealthBars()) + { + String fileBase = Skin.AROUND_2010.toString() + "/healthbar/"; + + SpritePixels frontSprite = getFileSpritePixels(fileBase + "front.png"); + SpritePixels backSprite = getFileSpritePixels(fileBase + "back.png"); + + SpritePixels frontSpriteLarge = getFileSpritePixels(fileBase + "front_large.png"); + SpritePixels backSpriteLarge = getFileSpritePixels(fileBase + "back_large.png"); + + HealthBarOverride override = new HealthBarOverride(frontSprite, backSprite, frontSpriteLarge, backSpriteLarge); + client.setHealthBarOverride(override); + } + else + { + client.setHealthBarOverride(null); + } + } + private void restoreWidgetDimensions() { for (WidgetOffset widgetOffset : WidgetOffset.values()) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/interfacestyles/2010/healthbar/back.png b/runelite-client/src/main/resources/net/runelite/client/plugins/interfacestyles/2010/healthbar/back.png new file mode 100644 index 0000000000..89e37c75bd Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/interfacestyles/2010/healthbar/back.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/interfacestyles/2010/healthbar/back_large.png b/runelite-client/src/main/resources/net/runelite/client/plugins/interfacestyles/2010/healthbar/back_large.png new file mode 100644 index 0000000000..c609c99d4e Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/interfacestyles/2010/healthbar/back_large.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/interfacestyles/2010/healthbar/front.png b/runelite-client/src/main/resources/net/runelite/client/plugins/interfacestyles/2010/healthbar/front.png new file mode 100644 index 0000000000..54da07dc63 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/interfacestyles/2010/healthbar/front.png differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/interfacestyles/2010/healthbar/front_large.png b/runelite-client/src/main/resources/net/runelite/client/plugins/interfacestyles/2010/healthbar/front_large.png new file mode 100644 index 0000000000..b7cc3e38b7 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/interfacestyles/2010/healthbar/front_large.png differ diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index ad25333d80..6c3d1f1ae0 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -41,6 +41,7 @@ import net.runelite.api.GameState; import net.runelite.api.GrandExchangeOffer; import net.runelite.api.GraphicsObject; import net.runelite.api.HashTable; +import net.runelite.api.HealthBarOverride; import net.runelite.api.HintArrowType; import net.runelite.api.Ignore; import net.runelite.api.IndexDataBase; @@ -186,6 +187,9 @@ public abstract class RSClientMixin implements RSClient .maximumSize(64) .build(); + @Inject + private static HealthBarOverride healthBarOverride; + @Inject public RSClientMixin() { @@ -1246,6 +1250,13 @@ public abstract class RSClientMixin implements RSClient client.getCallbacks().post(new UsernameChanged()); } + @Inject + @Override + public void setHealthBarOverride(HealthBarOverride override) + { + healthBarOverride = override; + } + @Override @Inject public int getTickCount() diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSHealthBarMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSHealthBarMixin.java new file mode 100644 index 0000000000..2a25c1a2a1 --- /dev/null +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSHealthBarMixin.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2019, 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.mixins; + +import net.runelite.api.HealthBarOverride; +import net.runelite.api.mixins.Copy; +import net.runelite.api.mixins.Mixin; +import net.runelite.api.mixins.Replace; +import net.runelite.api.mixins.Shadow; +import net.runelite.rs.api.RSHealthBar; +import net.runelite.rs.api.RSSpritePixels; + +@Mixin(RSHealthBar.class) +public abstract class RSHealthBarMixin implements RSHealthBar +{ + // Larger values are used for bosses like Corporeal Beast + private static final int DEFAULT_HEALTH_SCALE = 30; + + @Shadow("healthBarOverride") + private static HealthBarOverride healthBarOverride; + + @Copy("getHealthBarBackSprite") + abstract RSSpritePixels rs$getHealthBarBackSprite(); + + @Replace("getHealthBarBackSprite") + public RSSpritePixels rl$getHealthBarBackSprite() + { + /* + * If this combat info already uses sprites for health bars, + * use those instead, and don't override. + */ + RSSpritePixels pixels = rs$getHealthBarBackSprite(); + if (pixels != null) + { + return pixels; + } + + if (healthBarOverride == null) + { + return null; + } + + return getHealthScale() == DEFAULT_HEALTH_SCALE + ? (RSSpritePixels) healthBarOverride.backSprite + : (RSSpritePixels) healthBarOverride.backSpriteLarge; + } + + @Copy("getHealthBarFrontSprite") + abstract RSSpritePixels rs$getHealthBarFrontSprite(); + + @Replace("getHealthBarFrontSprite") + public RSSpritePixels rl$getHealthBarFrontSprite() + { + /* + * If this combat info already uses sprites for health bars, + * use those instead, and don't override. + */ + RSSpritePixels pixels = rs$getHealthBarFrontSprite(); + if (pixels != null) + { + return pixels; + } + + if (healthBarOverride == null) + { + return null; + } + + // 30 is the default size, large is for bosses like Corporeal Beast + return getHealthScale() == DEFAULT_HEALTH_SCALE + ? (RSSpritePixels) healthBarOverride.frontSprite + : (RSSpritePixels) healthBarOverride.frontSpriteLarge; + } +}