xp-tracker: add configurable labels to XpInfoBox
This commit allows users to change the XpInfoBox to which ever xp stat is available in the config menu. This also adds TTL in the form of hh:mm:ss to the info box
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
|
||||
* Copyright (c) 2020, Anthony <https://github.com/while-loop>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -95,10 +96,10 @@ class XpInfoBox extends JPanel
|
||||
|
||||
private final ProgressBar progressBar = new ProgressBar();
|
||||
|
||||
private final JLabel expGained = new JLabel();
|
||||
private final JLabel expHour = new JLabel();
|
||||
private final JLabel expLeft = new JLabel();
|
||||
private final JLabel actionsLeft = new JLabel();
|
||||
private final JLabel topLeftStat = new JLabel();
|
||||
private final JLabel bottomLeftStat = new JLabel();
|
||||
private final JLabel topRightStat = new JLabel();
|
||||
private final JLabel bottomRightStat = new JLabel();
|
||||
private final JMenuItem pauseSkill = new JMenuItem("Pause");
|
||||
private final JMenuItem canvasItem = new JMenuItem(ADD_STATE);
|
||||
|
||||
@@ -184,15 +185,16 @@ class XpInfoBox extends JPanel
|
||||
statsPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
statsPanel.setBorder(new EmptyBorder(9, 2, 9, 2));
|
||||
|
||||
expGained.setFont(FontManager.getRunescapeSmallFont());
|
||||
expHour.setFont(FontManager.getRunescapeSmallFont());
|
||||
expLeft.setFont(FontManager.getRunescapeSmallFont());
|
||||
actionsLeft.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
statsPanel.add(expGained);
|
||||
statsPanel.add(expLeft);
|
||||
statsPanel.add(expHour);
|
||||
statsPanel.add(actionsLeft);
|
||||
topLeftStat.setFont(FontManager.getRunescapeSmallFont());
|
||||
bottomLeftStat.setFont(FontManager.getRunescapeSmallFont());
|
||||
topRightStat.setFont(FontManager.getRunescapeSmallFont());
|
||||
bottomRightStat.setFont(FontManager.getRunescapeSmallFont());
|
||||
|
||||
statsPanel.add(topLeftStat); // top left
|
||||
statsPanel.add(topRightStat); // top right
|
||||
statsPanel.add(bottomLeftStat); // bottom left
|
||||
statsPanel.add(bottomRightStat); // bottom right
|
||||
|
||||
headerPanel.add(skillIcon, BorderLayout.WEST);
|
||||
headerPanel.add(statsPanel, BorderLayout.CENTER);
|
||||
@@ -243,11 +245,6 @@ class XpInfoBox extends JPanel
|
||||
|
||||
paused = skillPaused;
|
||||
|
||||
// Update information labels
|
||||
expGained.setText(htmlLabel("XP Gained: ", xpSnapshotSingle.getXpGainedInSession()));
|
||||
expLeft.setText(htmlLabel("XP Left: ", xpSnapshotSingle.getXpRemainingToGoal()));
|
||||
actionsLeft.setText(htmlLabel(xpSnapshotSingle.getActionType().getLabel() + ": ", xpSnapshotSingle.getActionsRemainingToGoal()));
|
||||
|
||||
// Update progress bar
|
||||
progressBar.setValue((int) xpSnapshotSingle.getSkillProgressToGoal());
|
||||
progressBar.setCenterLabel(TWO_DECIMAL_FORMAT.format(xpSnapshotSingle.getSkillProgressToGoal()) + "%");
|
||||
@@ -304,13 +301,29 @@ class XpInfoBox extends JPanel
|
||||
pauseSkill.setText("Pause");
|
||||
}
|
||||
|
||||
// Update information labels
|
||||
// Update exp per hour separately, every time (not only when there's an update)
|
||||
expHour.setText(htmlLabel("XP/Hour: ", xpSnapshotSingle.getXpPerHour()));
|
||||
topLeftStat.setText(htmlLabel(xpTrackerConfig.xpPanelLabel1(), xpSnapshotSingle));
|
||||
topRightStat.setText(htmlLabel(xpTrackerConfig.xpPanelLabel2(), xpSnapshotSingle));
|
||||
bottomLeftStat.setText(htmlLabel(xpTrackerConfig.xpPanelLabel3(), xpSnapshotSingle));
|
||||
bottomRightStat.setText(htmlLabel(xpTrackerConfig.xpPanelLabel4(), xpSnapshotSingle));
|
||||
}
|
||||
|
||||
static String htmlLabel(XpPanelLabel panelLabel, XpSnapshotSingle xpSnapshotSingle)
|
||||
{
|
||||
String key = panelLabel.getActionKey(xpSnapshotSingle) + ": ";
|
||||
String value = panelLabel.getValueFunc().apply(xpSnapshotSingle);
|
||||
return htmlLabel(key, value);
|
||||
}
|
||||
|
||||
static String htmlLabel(String key, int value)
|
||||
{
|
||||
String valueStr = QuantityFormatter.quantityToRSDecimalStack(value, true);
|
||||
return htmlLabel(key, valueStr);
|
||||
}
|
||||
|
||||
static String htmlLabel(String key, String valueStr)
|
||||
{
|
||||
return String.format(HTML_LABEL_TEMPLATE, ColorUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR), key, valueStr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Anthony <https://github.com/while-loop>
|
||||
* 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.function.Function;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.runelite.client.util.QuantityFormatter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum XpPanelLabel
|
||||
{
|
||||
TIME_TO_LEVEL("TTL", XpSnapshotSingle::getTimeTillGoalShort),
|
||||
|
||||
XP_GAINED("XP Gained", snap -> format(snap.getXpGainedInSession())),
|
||||
XP_HOUR("XP/hr", snap -> format(snap.getXpPerHour())),
|
||||
XP_LEFT("XP Left", snap -> format(snap.getXpRemainingToGoal())),
|
||||
|
||||
ACTIONS_LEFT("Actions", snap -> format(snap.getActionsRemainingToGoal())),
|
||||
ACTIONS_HOUR("Actions/hr", snap -> format(snap.getActionsPerHour())),
|
||||
ACTIONS_DONE("Actions Done", snap -> format(snap.getActionsInSession())),
|
||||
;
|
||||
|
||||
private final String key;
|
||||
private final Function<XpSnapshotSingle, String> valueFunc;
|
||||
|
||||
/**
|
||||
* Get the action key label based on if the Action type is an xp drop or kill
|
||||
*
|
||||
* @param snapshot
|
||||
* @return
|
||||
*/
|
||||
public String getActionKey(XpSnapshotSingle snapshot)
|
||||
{
|
||||
String actionKey = key;
|
||||
if (snapshot.getActionType() == XpActionType.ACTOR_HEALTH)
|
||||
{
|
||||
return actionKey.replace("Action", "Kill");
|
||||
}
|
||||
|
||||
return actionKey;
|
||||
}
|
||||
|
||||
private static String format(int val)
|
||||
{
|
||||
return QuantityFormatter.quantityToRSDecimalStack(val, true);
|
||||
}
|
||||
}
|
||||
@@ -44,4 +44,5 @@ class XpSnapshotSingle
|
||||
private int actionsRemainingToGoal;
|
||||
private int actionsPerHour;
|
||||
private String timeTillGoal;
|
||||
private String timeTillGoalShort;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Cameron <moberg@tuta.io>
|
||||
* Copyright (c) 2018, Levi <me@levischuck.com>
|
||||
* Copyright (c) 2020, Anthony <https://github.com/while-loop>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -128,24 +129,31 @@ class XpStateSingle
|
||||
return (xpGained / xpGoal) * 100;
|
||||
}
|
||||
|
||||
private String getTimeTillLevel()
|
||||
private long getSecondsTillLevel()
|
||||
{
|
||||
// Java 8 doesn't have good duration / period objects to represent spans of time that can be formatted
|
||||
// Rather than importing another dependency like joda time (which is practically built into java 10)
|
||||
// below will be a custom formatter that handles spans larger than 1 day
|
||||
long seconds = getTimeElapsedInSeconds();
|
||||
|
||||
if (seconds <= 0 || xpGained <= 0)
|
||||
{
|
||||
// Infinity symbol
|
||||
return "\u221e";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// formula is xpRemaining / xpPerSecond
|
||||
// xpPerSecond being xpGained / seconds
|
||||
// This can be simplified so division is only done once and we can work in whole numbers!
|
||||
long remainingSeconds = (getXpRemaining() * seconds) / xpGained;
|
||||
return (getXpRemaining() * seconds) / xpGained;
|
||||
}
|
||||
|
||||
// Java 8 doesn't have good duration / period objects to represent spans of time that can be formatted
|
||||
// Rather than importing another dependency like joda time (which is practically built into java 10)
|
||||
// below will be a custom formatter that handles spans larger than 1 day
|
||||
private String getTimeTillLevel()
|
||||
{
|
||||
long remainingSeconds = getSecondsTillLevel();
|
||||
if (remainingSeconds < 0)
|
||||
{
|
||||
return "\u221e";
|
||||
}
|
||||
|
||||
long durationDays = remainingSeconds / (24 * 60 * 60);
|
||||
long durationHours = (remainingSeconds % (24 * 60 * 60)) / (60 * 60);
|
||||
@@ -160,7 +168,29 @@ class XpStateSingle
|
||||
{
|
||||
return String.format("1 day %02d:%02d:%02d", durationHours, durationMinutes, durationSeconds);
|
||||
}
|
||||
else if (durationHours > 0)
|
||||
|
||||
// durationDays = 0 if we got here.
|
||||
// return time remaining in hh:mm:ss or mm:ss format
|
||||
return getTimeTillLevelShort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get time to level in `hh:mm:ss` or `mm:ss` format,
|
||||
* where `hh` can be > 24.
|
||||
* @return
|
||||
*/
|
||||
private String getTimeTillLevelShort()
|
||||
{
|
||||
long remainingSeconds = getSecondsTillLevel();
|
||||
if (remainingSeconds < 0)
|
||||
{
|
||||
return "\u221e";
|
||||
}
|
||||
|
||||
long durationHours = remainingSeconds / (60 * 60);
|
||||
long durationMinutes = (remainingSeconds % (60 * 60)) / 60;
|
||||
long durationSeconds = remainingSeconds % 60;
|
||||
if (durationHours > 0)
|
||||
{
|
||||
return String.format("%02d:%02d:%02d", durationHours, durationMinutes, durationSeconds);
|
||||
}
|
||||
@@ -269,6 +299,7 @@ class XpStateSingle
|
||||
.actionsRemainingToGoal(getActionsRemaining())
|
||||
.actionsPerHour(getActionsHr())
|
||||
.timeTillGoal(getTimeTillLevel())
|
||||
.timeTillGoalShort(getTimeTillLevelShort())
|
||||
.startGoalXp(startLevelExp)
|
||||
.endGoalXp(endLevelExp)
|
||||
.build();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Levi <me@levischuck.com>
|
||||
* Copyright (c) 2020, Anthony <https://github.com/while-loop>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -126,4 +127,49 @@ public interface XpTrackerConfig extends Config
|
||||
{
|
||||
return OnScreenDisplayModeBottom.XP_HOUR;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 7,
|
||||
keyName = "xpPanelLabel1",
|
||||
name = "Top-left XP info label",
|
||||
description = "Configures the information displayed in the top-left of XP info box"
|
||||
)
|
||||
default XpPanelLabel xpPanelLabel1()
|
||||
{
|
||||
return XpPanelLabel.XP_GAINED;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 8,
|
||||
keyName = "xpPanelLabel2",
|
||||
name = "Top-right XP info label",
|
||||
description = "Configures the information displayed in the top-right of XP info box"
|
||||
)
|
||||
|
||||
default XpPanelLabel xpPanelLabel2()
|
||||
{
|
||||
return XpPanelLabel.XP_LEFT;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 9,
|
||||
keyName = "xpPanelLabel3",
|
||||
name = "Bottom-left XP info label",
|
||||
description = "Configures the information displayed in the bottom-left of XP info box"
|
||||
)
|
||||
default XpPanelLabel xpPanelLabel3()
|
||||
{
|
||||
return XpPanelLabel.XP_HOUR;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 10,
|
||||
keyName = "xpPanelLabel4",
|
||||
name = "Bottom-right XP info label",
|
||||
description = "Configures the information displayed in the bottom-right of XP info box"
|
||||
)
|
||||
default XpPanelLabel xpPanelLabel4()
|
||||
{
|
||||
return XpPanelLabel.ACTIONS_LEFT;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user