diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsPlugin.java index b91fec472e..02cfdb0772 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsPlugin.java @@ -36,6 +36,7 @@ import javax.inject.Inject; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; +import net.runelite.api.Prayer; import net.runelite.api.Skill; import net.runelite.api.events.BoostedLevelChanged; import net.runelite.api.events.ConfigChanged; @@ -97,6 +98,8 @@ public class BoostsPlugin extends Plugin private BufferedImage overallIcon; + private boolean preserveBeenActive = false; + @Provides BoostsConfig provideConfig(ConfigManager configManager) { @@ -206,8 +209,39 @@ public class BoostsPlugin extends Plugin } } + /** + * Calculates the amount of time until boosted stats decay, + * accounting for the effect of preserve prayer. + * Preserve extends the time of boosted stats by 50% while active. + * The length of a boost is split into 4 sections of 15 seconds each. + * If the preserve prayer is active for the entire duration of the final + * section it will "activate" adding an additional 15 second section + * to the boost timing. If again the preserve prayer is active for that + * entire section a second 15 second section will be added. + * + * Preserve is only required to be on for the 4th and 5th sections of the boost timer + * to gain full effect (seconds 45-75). + * + * @return integer value in seconds until next boost change + */ public int getChangeTime() { - return 60 - (int) Duration.between(lastChange, Instant.now()).getSeconds(); + int timeSinceChange = timeSinceLastChange(); + boolean isPreserveActive = client.isPrayerActive(Prayer.PRESERVE); + + if ((isPreserveActive && (timeSinceChange < 45 || preserveBeenActive)) || timeSinceChange > 75) + { + preserveBeenActive = true; + return 90 - timeSinceChange; + } + + preserveBeenActive = false; + return (timeSinceChange > 60) ? 75 - timeSinceChange : 60 - timeSinceChange; } + + private int timeSinceLastChange() + { + return (int) Duration.between(lastChange, Instant.now()).getSeconds(); + } + }