diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatOverlay.java index 986321e966..73113bd0ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatOverlay.java @@ -258,7 +258,7 @@ public class ItemStatOverlay extends Overlay if (config.relative()) { - b.append(c.getRelative()); + b.append(c.getFormattedRelative()); } if (config.theoretical()) @@ -267,7 +267,7 @@ public class ItemStatOverlay extends Overlay { b.append("/"); } - b.append(c.getTheoretical()); + b.append(c.getFormattedTheoretical()); } if (config.absolute() && (config.relative() || config.theoretical())) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/RangeStatBoost.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/RangeStatBoost.java index abe47cea1c..13011b9f6a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/RangeStatBoost.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/RangeStatBoost.java @@ -42,33 +42,21 @@ public class RangeStatBoost extends SingleEffect @Override public StatChange effect(Client client) { - final StatChange a = this.a.effect(client); - final StatChange b = this.b.effect(client); + final StatChange changeA = this.a.effect(client); + final StatChange changeB = this.b.effect(client); - final StatChange r = new StatChange(); - r.setAbsolute(concat(a.getAbsolute(), b.getAbsolute())); - r.setRelative(concat(a.getRelative(), b.getRelative())); - r.setTheoretical(concat(a.getTheoretical(), b.getTheoretical())); - r.setStat(a.getStat()); + final RangeStatChange r = new RangeStatChange(); + r.setMinAbsolute(Math.min(changeA.getAbsolute(), changeB.getAbsolute())); + r.setAbsolute(Math.max(changeA.getAbsolute(), changeB.getAbsolute())); + r.setMinRelative(Math.min(changeA.getRelative(), changeB.getRelative())); + r.setRelative(Math.max(changeA.getRelative(), changeB.getRelative())); + r.setMinTheoretical(Math.min(changeA.getTheoretical(), changeB.getTheoretical())); + r.setTheoretical(Math.max(changeA.getTheoretical(), changeB.getTheoretical())); + r.setStat(changeA.getStat()); - final int avg = (a.getPositivity().ordinal() + b.getPositivity().ordinal()) / 2; + final int avg = (changeA.getPositivity().ordinal() + changeB.getPositivity().ordinal()) / 2; r.setPositivity(Positivity.values()[avg]); return r; } - - private String concat(String a, String b) - { - // If they share a operator, strip b's duplicate - if (a.length() > 1 && b.length() > 1) - { - final char a0 = a.charAt(0); - if ((a0 == '+' || a0 == '-' || a0 == '±') && b.charAt(0) == a0) - { - b = b.substring(1); - } - } - - return a + "~" + b; - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/RangeStatChange.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/RangeStatChange.java new file mode 100644 index 0000000000..90b614bf10 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/RangeStatChange.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2016-2019, Jordan Atwood + * 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.itemstats; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * A stat change which can result in different magnitudes of change to the stat + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class RangeStatChange extends StatChange +{ + /** + * Minimum relative change that will occur if the stat boost is applied now. + * In this class, {@code relative} is representative of the maximum relative change that will + * occur. + */ + private int minRelative; + + /** + * Minimum theoretical change that can occur before boost cap is enforced. + * In this class, {@code theoretical} is representative of the maximum theoretical change that + * will occur. + */ + private int minTheoretical; + + /** + * Minimum absolute total of the stat after applying the boost. + * In this class, {@code absolute} is representative of the maximum absolute change that will + * occur. + */ + private int minAbsolute; + + /** + * Returns a human-readable formatted relative boost. + * Should be the boost range in the format "±N" (for minimum -N and maximum +N values), + * "+MIN~MAX" (for minimum and maximum values of the same sign), + * "-MIN~+MAX" (for negative minimum and positive maximum values), or + * "+MAX" (for equal minimum and maximum values). + * + * @return The formatted relative boost amount + */ + @Override + public String getFormattedRelative() + { + return concat(minRelative, getRelative()); + } + + /** + * Returns a human-readable formatted theoretical boost. + * Should be the boost range in the format "±N" (for minimum -N and maximum +N values), + * "+MIN~MAX" (for minimum and maximum values of the same sign), + * "-MIN~+MAX" (for negative minimum and positive maximum values), or + * "+MAX" (for equal minimum and maximum values). + * + * @return The formatted theoretical boost amount + */ + @Override + public String getFormattedTheoretical() + { + return concat(minTheoretical, getTheoretical()); + } + + private static String concat(int changeA, int changeB) + { + if (changeA == changeB) + { + return formatBoost(changeA); + } + else if (changeA * -1 == changeB) + { + return "±" + Math.abs(changeA); + } + + final StringBuilder sb = new StringBuilder(); + + sb.append(String.format("%+d", changeA)); + sb.append('~'); + + // If they share a operator, strip b's duplicate + if (changeA < 0 && changeB < 0 + || changeA >= 0 && changeB >= 0) + { + sb.append(Math.abs(changeB)); + } + else + { + sb.append(String.format("%+d", changeB)); + } + + return sb.toString(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/StatBoost.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/StatBoost.java index 1bc59d7412..cc5f7797f2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/StatBoost.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/StatBoost.java @@ -88,10 +88,9 @@ public abstract class StatBoost extends SingleEffect { out.setPositivity(Positivity.WORSE); } - out.setAbsolute(Integer.toString(newValue)); - out.setRelative(String.format("%+d", delta)); - out.setTheoretical(String.format("%+d", calcedDelta)); + out.setAbsolute(newValue); + out.setRelative(delta); + out.setTheoretical(calcedDelta); return out; } - } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/StatChange.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/StatChange.java index 3157748083..e9453984f4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/StatChange.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/StatChange.java @@ -40,23 +40,48 @@ public class StatChange /** * Relative change that will occur if the stat boost is applied now. - * Should be a number prefixed by "+" or "-". */ - private String relative; + private int relative; /** * Theoretical change that can occur before boost cap is enforced. - * Should be a number prefixed by "+" or "-". */ - private String theoretical; + private int theoretical; /** * Absolute total of the stat after applying the boost. */ - private String absolute; + private int absolute; /** * How beneficial this stat boost will be to the player. */ private Positivity positivity; + + /** + * Returns a human-readable formatted relative boost. + * Should be the boost amount prefixed by "+" or "-". + * + * @return The formatted relative boost amount + */ + public String getFormattedRelative() + { + return formatBoost(relative); + } + + /** + * Returns a human-readable formatted theoretical boost. + * Should be the boost amount prefixed by "+" or "-". + * + * @return The formatted theoretical boost amount + */ + public String getFormattedTheoretical() + { + return formatBoost(theoretical); + } + + static String formatBoost(int boost) + { + return String.format("%+d", boost); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/special/SpicyStew.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/special/SpicyStew.java index 8dab7fd601..7eee548751 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/special/SpicyStew.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/special/SpicyStew.java @@ -132,11 +132,14 @@ public class SpicyStew implements Effect int currentBoost = currentValue - currentBase; // Can be negative int spiceBoostCapped = (currentBoost <= 0) ? spiceBoost : Math.max(0, spiceBoost - currentBoost); - StatChange change = new StatChange(); + final RangeStatChange change = new RangeStatChange(); change.setStat(stat); - change.setRelative("±" + spiceBoostCapped); - change.setTheoretical("±" + spiceBoost); - change.setAbsolute(String.valueOf(stat.getValue(client) + spiceBoostCapped)); + change.setMinRelative(-spiceBoost); + change.setRelative(spiceBoostCapped); + change.setMinTheoretical(-spiceBoost); + change.setTheoretical(spiceBoost); + change.setMinAbsolute(Math.max(-spiceBoost, -currentValue)); + change.setAbsolute(stat.getValue(client) + spiceBoostCapped); Positivity positivity; if (spiceBoostCapped == 0) @@ -155,5 +158,4 @@ public class SpicyStew implements Effect return change; } - } 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 0deb55c2ab..ada42169ad 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,8 +24,6 @@ */ package net.runelite.client.plugins.statusbars; -import com.google.common.base.Strings; -import com.google.common.primitives.Ints; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; @@ -196,28 +194,16 @@ class StatusBarsOverlay extends Overlay for (final StatChange c : statsChanges.getStatChanges()) { - final String strVar = c.getTheoretical(); - - if (Strings.isNullOrEmpty(strVar)) - { - continue; - } - - final Integer value = Ints.tryParse(strVar.startsWith("+") ? strVar.substring(1) : strVar); - - if (value == null) - { - continue; - } + final int theoreticalBoost = c.getTheoretical(); if (c.getStat().getName().equals(Skill.HITPOINTS.getName())) { - foodHealValue = value; + foodHealValue = theoreticalBoost; } if (c.getStat().getName().equals(Skill.PRAYER.getName())) { - prayerHealValue = value; + prayerHealValue = theoreticalBoost; } if (foodHealValue != 0 && prayerHealValue != 0)