Add feature to pause skill timers on logout or after idle period
This commit is contained in:
@@ -54,6 +54,15 @@ import net.runelite.client.util.SwingUtil;
|
||||
@Slf4j
|
||||
class XpInfoBox extends JPanel
|
||||
{
|
||||
// Templates
|
||||
private static final String HTML_TOOL_TIP_TEMPLATE =
|
||||
"<html>%s actions done<br/>"
|
||||
+ "%s actions/hr<br/>"
|
||||
+ "%s till goal lvl</html>";
|
||||
private static final String HTML_LABEL_TEMPLATE =
|
||||
"<html><body style='color:%s'>%s<span style='color:white'>%s</span></body></html>";
|
||||
|
||||
// Instance members
|
||||
private final JPanel panel;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@@ -74,6 +83,9 @@ class XpInfoBox extends JPanel
|
||||
private final JLabel expHour = new JLabel();
|
||||
private final JLabel expLeft = new JLabel();
|
||||
private final JLabel actionsLeft = new JLabel();
|
||||
private final JMenuItem pauseSkill = new JMenuItem("Pause");
|
||||
|
||||
private boolean paused = false;
|
||||
|
||||
XpInfoBox(XpTrackerPlugin xpTrackerPlugin, Client client, JPanel panel, Skill skill, SkillIconManager iconManager) throws IOException
|
||||
{
|
||||
@@ -98,12 +110,16 @@ class XpInfoBox extends JPanel
|
||||
final JMenuItem resetOthers = new JMenuItem("Reset others");
|
||||
resetOthers.addActionListener(e -> xpTrackerPlugin.resetOtherSkillState(skill));
|
||||
|
||||
// Create reset others menu
|
||||
pauseSkill.addActionListener(e -> xpTrackerPlugin.pauseSkill(skill, !paused));
|
||||
|
||||
// Create popup menu
|
||||
final JPopupMenu popupMenu = new JPopupMenu();
|
||||
popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
popupMenu.add(openXpTracker);
|
||||
popupMenu.add(reset);
|
||||
popupMenu.add(resetOthers);
|
||||
popupMenu.add(pauseSkill);
|
||||
|
||||
JLabel skillIcon = new JLabel(new ImageIcon(iconManager.getSkillImage(skill)));
|
||||
skillIcon.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
@@ -138,6 +154,7 @@ class XpInfoBox extends JPanel
|
||||
progressBar.setMaximumValue(100);
|
||||
progressBar.setBackground(new Color(61, 56, 49));
|
||||
progressBar.setForeground(SkillColor.values()[skill.ordinal()].getColor());
|
||||
progressBar.setDimmedText("Paused");
|
||||
|
||||
progressWrapper.add(progressBar, BorderLayout.NORTH);
|
||||
|
||||
@@ -157,12 +174,12 @@ class XpInfoBox extends JPanel
|
||||
panel.revalidate();
|
||||
}
|
||||
|
||||
void update(boolean updated, XpSnapshotSingle xpSnapshotSingle)
|
||||
void update(boolean updated, boolean paused, XpSnapshotSingle xpSnapshotSingle)
|
||||
{
|
||||
SwingUtilities.invokeLater(() -> rebuildAsync(updated, xpSnapshotSingle));
|
||||
SwingUtilities.invokeLater(() -> rebuildAsync(updated, paused, xpSnapshotSingle));
|
||||
}
|
||||
|
||||
private void rebuildAsync(boolean updated, XpSnapshotSingle xpSnapshotSingle)
|
||||
private void rebuildAsync(boolean updated, boolean skillPaused, XpSnapshotSingle xpSnapshotSingle)
|
||||
{
|
||||
if (updated)
|
||||
{
|
||||
@@ -172,6 +189,8 @@ class XpInfoBox extends JPanel
|
||||
panel.revalidate();
|
||||
}
|
||||
|
||||
paused = skillPaused;
|
||||
|
||||
// Update information labels
|
||||
expGained.setText(htmlLabel("XP Gained: ", xpSnapshotSingle.getXpGainedInSession()));
|
||||
expLeft.setText(htmlLabel("XP Left: ", xpSnapshotSingle.getXpRemainingToGoal()));
|
||||
@@ -181,28 +200,42 @@ class XpInfoBox extends JPanel
|
||||
progressBar.setValue(xpSnapshotSingle.getSkillProgressToGoal());
|
||||
progressBar.setCenterLabel(xpSnapshotSingle.getSkillProgressToGoal() + "%");
|
||||
progressBar.setLeftLabel("Lvl. " + xpSnapshotSingle.getStartLevel());
|
||||
progressBar.setRightLabel("Lvl. " + (xpSnapshotSingle.getEndLevel()));
|
||||
progressBar.setRightLabel("Lvl. " + xpSnapshotSingle.getEndLevel());
|
||||
|
||||
progressBar.setToolTipText("<html>"
|
||||
+ xpSnapshotSingle.getActionsInSession() + " actions done"
|
||||
+ "<br/>"
|
||||
+ xpSnapshotSingle.getActionsPerHour() + " actions/hr"
|
||||
+ "<br/>"
|
||||
+ xpSnapshotSingle.getTimeTillGoal() + " till goal lvl"
|
||||
+ "</html>");
|
||||
progressBar.setToolTipText(String.format(
|
||||
HTML_TOOL_TIP_TEMPLATE,
|
||||
xpSnapshotSingle.getActionsInSession(),
|
||||
xpSnapshotSingle.getActionsPerHour(),
|
||||
xpSnapshotSingle.getTimeTillGoal()));
|
||||
|
||||
progressBar.setDimmed(skillPaused);
|
||||
|
||||
progressBar.repaint();
|
||||
}
|
||||
else if (!paused && skillPaused)
|
||||
{
|
||||
// React to the skill state now being paused
|
||||
progressBar.setDimmed(true);
|
||||
progressBar.repaint();
|
||||
paused = true;
|
||||
pauseSkill.setText("Unpause");
|
||||
}
|
||||
else if (paused && !skillPaused)
|
||||
{
|
||||
// React to the skill being unpaused (without update)
|
||||
progressBar.setDimmed(false);
|
||||
progressBar.repaint();
|
||||
paused = false;
|
||||
pauseSkill.setText("Pause");
|
||||
}
|
||||
|
||||
// Update exp per hour seperately, everytime (not only when there's an update)
|
||||
// Update exp per hour separately, every time (not only when there's an update)
|
||||
expHour.setText(htmlLabel("XP/Hour: ", xpSnapshotSingle.getXpPerHour()));
|
||||
}
|
||||
|
||||
static String htmlLabel(String key, int value)
|
||||
{
|
||||
String valueStr = StackFormatter.quantityToRSDecimalStack(value);
|
||||
|
||||
return "<html><body style = 'color:" + SwingUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR) + "'>" + key + "<span style = 'color:white'>" + valueStr + "</span></body></html>";
|
||||
return String.format(HTML_LABEL_TEMPLATE, SwingUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR), key, valueStr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -172,13 +172,13 @@ class XpPanel extends PluginPanel
|
||||
}
|
||||
}
|
||||
|
||||
void updateSkillExperience(boolean updated, Skill skill, XpSnapshotSingle xpSnapshotSingle)
|
||||
void updateSkillExperience(boolean updated, boolean paused, Skill skill, XpSnapshotSingle xpSnapshotSingle)
|
||||
{
|
||||
final XpInfoBox xpInfoBox = infoBoxes.get(skill);
|
||||
|
||||
if (xpInfoBox != null)
|
||||
{
|
||||
xpInfoBox.update(updated, xpSnapshotSingle);
|
||||
xpInfoBox.update(updated, paused, xpSnapshotSingle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Levi <me@levischuck.com>
|
||||
* 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.xptracker;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import net.runelite.api.Skill;
|
||||
|
||||
class XpPauseState
|
||||
{
|
||||
// Internal state
|
||||
private final Map<Skill, XpPauseStateSingle> skillPauses = new EnumMap<>(Skill.class);
|
||||
private boolean cachedIsLoggedIn = false;
|
||||
|
||||
boolean pauseSkill(Skill skill)
|
||||
{
|
||||
return findPauseState(skill).manualPause();
|
||||
}
|
||||
|
||||
boolean unpauseSkill(Skill skill)
|
||||
{
|
||||
return findPauseState(skill).unpause();
|
||||
}
|
||||
|
||||
boolean isPaused(Skill skill)
|
||||
{
|
||||
return findPauseState(skill).isPaused();
|
||||
}
|
||||
|
||||
void tickXp(Skill skill, int currentXp, int pauseAfterMinutes)
|
||||
{
|
||||
final XpPauseStateSingle state = findPauseState(skill);
|
||||
|
||||
if (state.getXp() != currentXp)
|
||||
{
|
||||
state.xpChanged(currentXp);
|
||||
}
|
||||
else if (pauseAfterMinutes > 0)
|
||||
{
|
||||
final long now = System.currentTimeMillis();
|
||||
final int pauseAfterMillis = pauseAfterMinutes * 60 * 1000;
|
||||
final long lastChangeMillis = state.getLastChangeMillis();
|
||||
// When config.pauseSkillAfter is 0, it is effectively disabled
|
||||
if (lastChangeMillis != 0 && (now - lastChangeMillis) >= pauseAfterMillis)
|
||||
{
|
||||
state.timeout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tickLogout(boolean pauseOnLogout, boolean loggedIn)
|
||||
{
|
||||
// Deduplicated login and logout calls
|
||||
if (!cachedIsLoggedIn && loggedIn)
|
||||
{
|
||||
cachedIsLoggedIn = true;
|
||||
|
||||
for (Skill skill : Skill.values())
|
||||
{
|
||||
findPauseState(skill).login();
|
||||
}
|
||||
}
|
||||
else if (cachedIsLoggedIn && !loggedIn)
|
||||
{
|
||||
cachedIsLoggedIn = false;
|
||||
|
||||
// If configured, then let the pause state know to pause with reason: logout
|
||||
if (pauseOnLogout)
|
||||
{
|
||||
for (Skill skill : Skill.values())
|
||||
{
|
||||
findPauseState(skill).logout();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private XpPauseStateSingle findPauseState(Skill skill)
|
||||
{
|
||||
return skillPauses.computeIfAbsent(skill, XpPauseStateSingle::new);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Levi <me@levischuck.com>
|
||||
* 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.xptracker;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.api.Skill;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
class XpPauseStateSingle
|
||||
{
|
||||
@Getter
|
||||
private final Skill skill;
|
||||
private final Set<XpPauseReason> pauseReasons = EnumSet.noneOf(XpPauseReason.class);
|
||||
@Getter
|
||||
private long lastChangeMillis;
|
||||
@Getter
|
||||
private int xp;
|
||||
|
||||
boolean isPaused()
|
||||
{
|
||||
return !pauseReasons.isEmpty();
|
||||
}
|
||||
|
||||
boolean login()
|
||||
{
|
||||
return pauseReasons.remove(XpPauseReason.PAUSED_LOGOUT);
|
||||
}
|
||||
|
||||
boolean logout()
|
||||
{
|
||||
return pauseReasons.add(XpPauseReason.PAUSED_LOGOUT);
|
||||
}
|
||||
|
||||
boolean timeout()
|
||||
{
|
||||
return pauseReasons.add(XpPauseReason.PAUSED_TIMEOUT);
|
||||
}
|
||||
|
||||
boolean manualPause()
|
||||
{
|
||||
return pauseReasons.add(XpPauseReason.PAUSE_MANUAL);
|
||||
}
|
||||
|
||||
boolean xpChanged(int xp)
|
||||
{
|
||||
this.xp = xp;
|
||||
this.lastChangeMillis = System.currentTimeMillis();
|
||||
return clearAll();
|
||||
}
|
||||
|
||||
boolean unpause()
|
||||
{
|
||||
this.lastChangeMillis = System.currentTimeMillis();
|
||||
return clearAll();
|
||||
}
|
||||
|
||||
private boolean clearAll()
|
||||
{
|
||||
if (pauseReasons.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pauseReasons.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
private enum XpPauseReason
|
||||
{
|
||||
PAUSE_MANUAL,
|
||||
PAUSED_LOGOUT,
|
||||
PAUSED_TIMEOUT
|
||||
}
|
||||
}
|
||||
@@ -120,6 +120,11 @@ class XpState
|
||||
}
|
||||
}
|
||||
|
||||
void tick(Skill skill, long delta)
|
||||
{
|
||||
getSkill(skill).tick(delta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forcefully initialize a skill with a known start XP from the current XP.
|
||||
* This is used in resetAndInitState by the plugin. It should not result in showing the XP in the UI.
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.xptracker;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -45,7 +43,7 @@ class XpStateSingle
|
||||
@Getter
|
||||
private int xpGained = 0;
|
||||
|
||||
private Instant skillTimeStart = null;
|
||||
private long skillTime = 0;
|
||||
private int actions = 0;
|
||||
private int startLevelExp = 0;
|
||||
private int endLevelExp = 0;
|
||||
@@ -65,7 +63,7 @@ class XpStateSingle
|
||||
|
||||
private int toHourly(int value)
|
||||
{
|
||||
if (skillTimeStart == null)
|
||||
if (skillTime == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -75,7 +73,7 @@ class XpStateSingle
|
||||
|
||||
private long getTimeElapsedInSeconds()
|
||||
{
|
||||
if (skillTimeStart == null)
|
||||
if (skillTime == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -84,7 +82,7 @@ class XpStateSingle
|
||||
// To prevent that, pretend the skill has been active for a minute (60 seconds)
|
||||
// This will create a lower estimate for the first minute,
|
||||
// but it isn't ridiculous like saying 2 billion XP per hour.
|
||||
return Math.max(60, Duration.between(skillTimeStart, Instant.now()).getSeconds());
|
||||
return Math.max(60, skillTime / 1000);
|
||||
}
|
||||
|
||||
private int getXpRemaining()
|
||||
@@ -229,15 +227,14 @@ class XpStateSingle
|
||||
endLevelExp = goalEndXp;
|
||||
}
|
||||
|
||||
// If this is first time we are updating, we just started tracking
|
||||
if (skillTimeStart == null)
|
||||
{
|
||||
skillTimeStart = Instant.now();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void tick(long delta)
|
||||
{
|
||||
skillTime += delta;
|
||||
}
|
||||
|
||||
XpSnapshotSingle snapshot()
|
||||
{
|
||||
return XpSnapshotSingle.builder()
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Levi <me@levischuck.com>
|
||||
* 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.xptracker;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("xpTracker")
|
||||
public interface XpTrackerConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "logoutPausing",
|
||||
name = "Pause on Logout",
|
||||
description = "Configures whether skills should pause on logout"
|
||||
)
|
||||
default boolean pauseOnLogout()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "pauseSkillAfter",
|
||||
name = "Auto pause after",
|
||||
description = "Configures how many minutes passes before pausing a skill while in game and there's no XP, 0 means disabled"
|
||||
)
|
||||
default int pauseSkillAfter()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,9 @@ package net.runelite.client.plugins.xptracker;
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.google.inject.Binder;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Objects;
|
||||
import javax.imageio.ImageIO;
|
||||
@@ -43,10 +45,12 @@ import net.runelite.api.WorldType;
|
||||
import net.runelite.api.events.ExperienceChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import static net.runelite.client.plugins.xptracker.XpWorldType.NORMAL;
|
||||
import net.runelite.client.task.Schedule;
|
||||
import net.runelite.client.ui.NavigationButton;
|
||||
import net.runelite.client.ui.PluginToolbar;
|
||||
import net.runelite.http.api.xp.XpClient;
|
||||
@@ -68,15 +72,24 @@ public class XpTrackerPlugin extends Plugin
|
||||
@Inject
|
||||
private SkillIconManager skillIconManager;
|
||||
|
||||
@Inject
|
||||
private XpTrackerConfig xpTrackerConfig;
|
||||
|
||||
private NavigationButton navButton;
|
||||
private XpPanel xpPanel;
|
||||
|
||||
private final XpState xpState = new XpState();
|
||||
|
||||
private XpWorldType lastWorldType;
|
||||
private String lastUsername;
|
||||
private long lastTickMillis = 0;
|
||||
|
||||
private final XpClient xpClient = new XpClient();
|
||||
private final XpState xpState = new XpState();
|
||||
private final XpPauseState xpPauseState = new XpPauseState();
|
||||
|
||||
@Provides
|
||||
XpTrackerConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(XpTrackerConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(Binder binder)
|
||||
@@ -229,7 +242,7 @@ public class XpTrackerPlugin extends Plugin
|
||||
final XpUpdateResult updateResult = xpState.updateSkill(skill, currentXp, startGoalXp, endGoalXp);
|
||||
|
||||
final boolean updated = XpUpdateResult.UPDATED.equals(updateResult);
|
||||
xpPanel.updateSkillExperience(updated, skill, xpState.getSkillSnapshot(skill));
|
||||
xpPanel.updateSkillExperience(updated, xpPauseState.isPaused(skill), skill, xpState.getSkillSnapshot(skill));
|
||||
xpState.recalculateTotal();
|
||||
xpPanel.updateTotal(xpState.getTotalSnapshot());
|
||||
}
|
||||
@@ -237,14 +250,7 @@ public class XpTrackerPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
// Rebuild calculated values like xp/hr in panel
|
||||
for (Skill skill : Skill.values())
|
||||
{
|
||||
xpPanel.updateSkillExperience(false, skill, xpState.getSkillSnapshot(skill));
|
||||
}
|
||||
|
||||
xpState.recalculateTotal();
|
||||
xpPanel.updateTotal(xpState.getTotalSnapshot());
|
||||
rebuildSkills();
|
||||
}
|
||||
|
||||
XpSnapshotSingle getSkillSnapshot(Skill skill)
|
||||
@@ -361,4 +367,59 @@ public class XpTrackerPlugin extends Plugin
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Schedule(
|
||||
period = 1,
|
||||
unit = ChronoUnit.SECONDS
|
||||
)
|
||||
public void tickSkillTimes()
|
||||
{
|
||||
// Adjust unpause states
|
||||
for (Skill skill : Skill.values())
|
||||
{
|
||||
xpPauseState.tickXp(skill, client.getSkillExperience(skill), xpTrackerConfig.pauseSkillAfter());
|
||||
}
|
||||
|
||||
xpPauseState.tickLogout(xpTrackerConfig.pauseOnLogout(), !GameState.LOGIN_SCREEN.equals(client.getGameState()));
|
||||
|
||||
if (lastTickMillis == 0)
|
||||
{
|
||||
lastTickMillis = System.currentTimeMillis();
|
||||
return;
|
||||
}
|
||||
|
||||
final long nowMillis = System.currentTimeMillis();
|
||||
final long tickDelta = nowMillis - lastTickMillis;
|
||||
lastTickMillis = nowMillis;
|
||||
|
||||
for (Skill skill : Skill.values())
|
||||
{
|
||||
if (!xpPauseState.isPaused(skill))
|
||||
{
|
||||
xpState.tick(skill, tickDelta);
|
||||
}
|
||||
}
|
||||
|
||||
rebuildSkills();
|
||||
}
|
||||
|
||||
private void rebuildSkills()
|
||||
{
|
||||
// Rebuild calculated values like xp/hr in panel
|
||||
for (Skill skill : Skill.values())
|
||||
{
|
||||
xpPanel.updateSkillExperience(false, xpPauseState.isPaused(skill), skill, xpState.getSkillSnapshot(skill));
|
||||
}
|
||||
|
||||
xpState.recalculateTotal();
|
||||
xpPanel.updateTotal(xpState.getTotalSnapshot());
|
||||
}
|
||||
|
||||
void pauseSkill(Skill skill, boolean pause)
|
||||
{
|
||||
if (pause ? xpPauseState.pauseSkill(skill) : xpPauseState.unpauseSkill(skill))
|
||||
{
|
||||
xpPanel.updateSkillExperience(false, xpPauseState.isPaused(skill), skill, xpState.getSkillSnapshot(skill));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user