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:
Anthony Alves
2020-04-20 20:33:48 -04:00
parent 95481bbbd1
commit 3cb2f68725
5 changed files with 188 additions and 26 deletions

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -44,4 +44,5 @@ class XpSnapshotSingle
private int actionsRemainingToGoal;
private int actionsPerHour;
private String timeTillGoal;
private String timeTillGoalShort;
}

View File

@@ -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();

View File

@@ -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;
}
}