Add support for preserving boost indicators

- Add support for showing boost indicators after no stat is boosted based
on last accurate change.
- Change the  counter to be in ticks in order to get most accurate
results possible

Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
This commit is contained in:
Tomas Slusny
2018-06-24 14:31:58 +02:00
committed by Adam
parent 2ab19503df
commit 91991a5eb6
4 changed files with 160 additions and 110 deletions

View File

@@ -31,6 +31,13 @@ import net.runelite.client.config.ConfigItem;
@ConfigGroup("boosts") @ConfigGroup("boosts")
public interface BoostsConfig extends Config public interface BoostsConfig extends Config
{ {
enum DisplayChangeMode
{
ALWAYS,
BOOSTED,
NEVER
}
@ConfigItem( @ConfigItem(
keyName = "enableSkill", keyName = "enableSkill",
name = "Enable Skill Boosts", name = "Enable Skill Boosts",
@@ -65,14 +72,14 @@ public interface BoostsConfig extends Config
} }
@ConfigItem( @ConfigItem(
keyName = "displayNextChange", keyName = "displayNextBuffChange",
name = "Display next buff change", name = "Display next buff change",
description = "Configures whether or not to display when the next buffed stat change will be", description = "Configures whether or not to display when the next buffed stat change will be",
position = 4 position = 4
) )
default boolean displayNextBuffChange() default DisplayChangeMode displayNextBuffChange()
{ {
return true; return DisplayChangeMode.BOOSTED;
} }
@ConfigItem( @ConfigItem(
@@ -81,9 +88,9 @@ public interface BoostsConfig extends Config
description = "Configures whether or not to display when the next debuffed stat change will be", description = "Configures whether or not to display when the next debuffed stat change will be",
position = 5 position = 5
) )
default boolean displayNextDebuffChange() default DisplayChangeMode displayNextDebuffChange()
{ {
return false; return DisplayChangeMode.NEVER;
} }
@ConfigItem( @ConfigItem(

View File

@@ -63,71 +63,63 @@ class BoostsOverlay extends Overlay
panelComponent.getChildren().clear(); panelComponent.getChildren().clear();
if (config.displayNextBuffChange()) int nextChange = plugin.getChangeDownTicks();
if (nextChange != -1)
{ {
int nextChange = plugin.getChangeDownTime();
if (nextChange != -1)
{
panelComponent.getChildren().add(LineComponent.builder()
.left("Next + restore in")
.right(String.valueOf(nextChange))
.build());
}
}
if (config.displayNextDebuffChange())
{
int nextChange = plugin.getChangeUpTime();
if (nextChange != -1)
{
panelComponent.getChildren().add(LineComponent.builder()
.left("Next - restore in")
.right(String.valueOf(nextChange))
.build());
}
}
if (!plugin.canShowBoosts())
{
return null;
}
for (Skill skill : plugin.getShownSkills())
{
final int boosted = client.getBoostedSkillLevel(skill);
final int base = client.getRealSkillLevel(skill);
if (boosted == base)
{
continue;
}
final int boost = boosted - base;
final Color strColor = getTextColor(boost);
String str;
if (config.useRelativeBoost())
{
str = String.valueOf(boost);
if (boost > 0)
{
str = "+" + str;
}
}
else
{
str = "<col=" + Integer.toHexString(strColor.getRGB() & 0xFFFFFF) + ">" + boosted + "<col=ffffff>/" + base;
}
panelComponent.getChildren().add(LineComponent.builder() panelComponent.getChildren().add(LineComponent.builder()
.left(skill.getName()) .left("Next + restore in")
.right(str) .right(String.valueOf(plugin.getChangeTime(nextChange)))
.rightColor(strColor)
.build()); .build());
} }
nextChange = plugin.getChangeUpTicks();
if (nextChange != -1)
{
panelComponent.getChildren().add(LineComponent.builder()
.left("Next - restore in")
.right(String.valueOf(plugin.getChangeTime(nextChange)))
.build());
}
if (plugin.canShowBoosts())
{
for (Skill skill : plugin.getShownSkills())
{
final int boosted = client.getBoostedSkillLevel(skill);
final int base = client.getRealSkillLevel(skill);
if (boosted == base)
{
continue;
}
final int boost = boosted - base;
final Color strColor = getTextColor(boost);
String str;
if (config.useRelativeBoost())
{
str = String.valueOf(boost);
if (boost > 0)
{
str = "+" + str;
}
}
else
{
str = "<col=" + Integer.toHexString(strColor.getRGB() & 0xFFFFFF) + ">" + boosted + "<col=ffffff>/" + base;
}
panelComponent.getChildren().add(LineComponent.builder()
.left(skill.getName())
.right(str)
.rightColor(strColor)
.build());
}
}
return panelComponent.render(graphics); return panelComponent.render(graphics);
} }

View File

@@ -27,13 +27,12 @@ package net.runelite.client.plugins.boosts;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.eventbus.Subscribe; import com.google.common.eventbus.Subscribe;
import com.google.inject.Provides; import com.google.inject.Provides;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client; import net.runelite.api.Client;
@@ -41,6 +40,7 @@ import net.runelite.api.Prayer;
import net.runelite.api.Skill; import net.runelite.api.Skill;
import net.runelite.api.events.BoostedLevelChanged; import net.runelite.api.events.BoostedLevelChanged;
import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GameTick; import net.runelite.api.events.GameTick;
import net.runelite.client.Notifier; import net.runelite.client.Notifier;
import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigManager;
@@ -56,6 +56,7 @@ import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
tags = {"combat", "notifications", "skilling", "overlay"} tags = {"combat", "notifications", "skilling", "overlay"}
) )
@Slf4j @Slf4j
@Singleton
public class BoostsPlugin extends Plugin public class BoostsPlugin extends Plugin
{ {
private static final Set<Skill> BOOSTABLE_COMBAT_SKILLS = ImmutableSet.of( private static final Set<Skill> BOOSTABLE_COMBAT_SKILLS = ImmutableSet.of(
@@ -97,9 +98,10 @@ public class BoostsPlugin extends Plugin
private boolean isChangedDown = false; private boolean isChangedDown = false;
private boolean isChangedUp = false; private boolean isChangedUp = false;
private final int[] lastSkillLevels = new int[Skill.values().length - 1]; private final int[] lastSkillLevels = new int[Skill.values().length - 1];
private Instant lastChangeDown; private int lastChangeDown = -1;
private Instant lastChangeUp; private int lastChangeUp = -1;
private boolean preserveBeenActive = false; private boolean preserveBeenActive = false;
private long lastTickMillis;
@Provides @Provides
BoostsConfig provideConfig(ConfigManager configManager) BoostsConfig provideConfig(ConfigManager configManager)
@@ -137,12 +139,25 @@ public class BoostsPlugin extends Plugin
overlayManager.remove(boostsOverlay); overlayManager.remove(boostsOverlay);
infoBoxManager.removeIf(t -> t instanceof BoostIndicator || t instanceof StatChangeIndicator); infoBoxManager.removeIf(t -> t instanceof BoostIndicator || t instanceof StatChangeIndicator);
preserveBeenActive = false; preserveBeenActive = false;
lastChangeDown = null; lastChangeDown = -1;
lastChangeUp = null; lastChangeUp = -1;
isChangedUp = false; isChangedUp = false;
isChangedDown = false; isChangedDown = false;
} }
@Subscribe
public void onGameStateChanged(GameStateChanged event)
{
switch (event.getGameState())
{
case LOGIN_SCREEN:
case HOPPING:
// After world hop and log out timers are in undefined state so just reset
lastChangeDown = -1;
lastChangeUp = -1;
}
}
@Subscribe @Subscribe
public void onConfigChanged(ConfigChanged event) public void onConfigChanged(ConfigChanged event)
{ {
@@ -152,6 +167,16 @@ public class BoostsPlugin extends Plugin
} }
updateShownSkills(); updateShownSkills();
if (config.displayNextBuffChange() == BoostsConfig.DisplayChangeMode.NEVER)
{
lastChangeDown = -1;
}
if (config.displayNextDebuffChange() == BoostsConfig.DisplayChangeMode.NEVER)
{
lastChangeUp = -1;
}
} }
@Subscribe @Subscribe
@@ -171,13 +196,13 @@ public class BoostsPlugin extends Plugin
if (cur == last - 1) if (cur == last - 1)
{ {
// Stat was restored down (from buff) // Stat was restored down (from buff)
lastChangeDown = Instant.now(); lastChangeDown = client.getTickCount();
} }
if (cur == last + 1) if (cur == last + 1)
{ {
// Stat was restored up (from debuff) // Stat was restored up (from debuff)
lastChangeUp = Instant.now(); lastChangeUp = client.getTickCount();
} }
lastSkillLevels[skillIdx] = cur; lastSkillLevels[skillIdx] = cur;
@@ -200,14 +225,42 @@ public class BoostsPlugin extends Plugin
@Subscribe @Subscribe
public void onGameTick(GameTick event) public void onGameTick(GameTick event)
{ {
if (config.displayNextDebuffChange() && getChangeUpTime() < 0) lastTickMillis = System.currentTimeMillis();
if (getChangeUpTicks() <= 0)
{ {
lastChangeUp = null; switch (config.displayNextDebuffChange())
{
case ALWAYS:
if (lastChangeUp != -1)
{
lastChangeUp = client.getTickCount();
}
break;
case BOOSTED:
case NEVER:
lastChangeUp = -1;
break;
}
} }
if (config.displayNextBuffChange() && getChangeDownTime() < 0) if (getChangeDownTicks() <= 0)
{ {
lastChangeDown = null; switch (config.displayNextBuffChange())
{
case ALWAYS:
if (lastChangeDown != -1)
{
lastChangeDown = client.getTickCount();
}
break;
case BOOSTED:
case NEVER:
lastChangeDown = -1;
break;
}
} }
} }
@@ -271,42 +324,54 @@ public class BoostsPlugin extends Plugin
* Preserve is only required to be on for the 4th and 5th sections of the boost timer * Preserve is only required to be on for the 4th and 5th sections of the boost timer
* to gain full effect (seconds 45-75). * to gain full effect (seconds 45-75).
* *
* @return integer value in seconds until next boost change * @return integer value in ticks until next boost change
*/ */
int getChangeDownTime() int getChangeDownTicks()
{ {
if (lastChangeDown == null || !isChangedUp) if (lastChangeDown == -1 || (config.displayNextBuffChange() == BoostsConfig.DisplayChangeMode.BOOSTED && !isChangedUp))
{ {
return -1; return -1;
} }
int timeSinceChange = (int) Duration.between(lastChangeDown, Instant.now()).getSeconds(); int ticksSinceChange = client.getTickCount() - lastChangeDown;
boolean isPreserveActive = client.isPrayerActive(Prayer.PRESERVE); boolean isPreserveActive = client.isPrayerActive(Prayer.PRESERVE);
if ((isPreserveActive && (timeSinceChange < 45 || preserveBeenActive)) || timeSinceChange > 75) if ((isPreserveActive && (ticksSinceChange < 75 || preserveBeenActive)) || ticksSinceChange > 125)
{ {
preserveBeenActive = true; preserveBeenActive = true;
return 90 - timeSinceChange; return 150 - ticksSinceChange;
} }
preserveBeenActive = false; preserveBeenActive = false;
return (timeSinceChange > 60) ? 75 - timeSinceChange : 60 - timeSinceChange; return (ticksSinceChange > 100) ? 125 - ticksSinceChange : 100 - ticksSinceChange;
} }
/** /**
* Restoration from debuff is separate timer as restoration from buff, and is always ticking, so just find * Restoration from debuff is separate timer as restoration from buff because of preserve messing up the buff timer.
* diff between last change up and now and limit it to cycles of 60. * Restoration timer is always in 100 tick cycles.
* *
* @return integer value in seconds until next stat restoration up * @return integer value in ticks until next stat restoration up
*/ */
int getChangeUpTime() int getChangeUpTicks()
{ {
if (lastChangeUp == null || !isChangedDown) if (lastChangeUp == -1 || (config.displayNextDebuffChange() == BoostsConfig.DisplayChangeMode.BOOSTED && !isChangedDown))
{ {
return -1; return -1;
} }
int timeSinceChange = (int) Duration.between(lastChangeUp, Instant.now()).getSeconds(); int ticksSinceChange = client.getTickCount() - lastChangeUp;
return 60 - timeSinceChange; return 100 - ticksSinceChange;
} }
}
/**
* Converts tick-based time to accurate second time
* @param time tick-based time
* @return second-based time
*/
int getChangeTime(final int time)
{
final long diff = System.currentTimeMillis() - lastTickMillis;
return time != -1 ? (int)(time * 0.6 - (diff / 1000d)) : time;
}
}

View File

@@ -48,33 +48,19 @@ public class StatChangeIndicator extends InfoBox
@Override @Override
public String getText() public String getText()
{ {
return String.format("%02d", up ? plugin.getChangeUpTime() : plugin.getChangeDownTime()); return String.format("%02d", plugin.getChangeTime(up ? plugin.getChangeUpTicks() : plugin.getChangeDownTicks()));
} }
@Override @Override
public Color getTextColor() public Color getTextColor()
{ {
final int time = up ? plugin.getChangeUpTime() : plugin.getChangeDownTime(); return (up ? plugin.getChangeUpTicks() : plugin.getChangeDownTicks()) < 10 ? Color.RED.brighter() : Color.WHITE;
if (time < 6)
{
return Color.RED.brighter();
}
return Color.WHITE;
} }
@Override @Override
public boolean render() public boolean render()
{ {
final int time = up ? plugin.getChangeUpTime() : plugin.getChangeDownTime(); final int time = up ? plugin.getChangeUpTicks() : plugin.getChangeDownTicks();
return config.displayIndicators() && time != -1;
if (time == -1)
{
return false;
}
final boolean enable = up ? config.displayNextDebuffChange() : config.displayNextBuffChange();
return config.displayIndicators() && enable;
} }
} }