xp tracker: add goal time formatting option
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Dasgust <dasgust@gmail.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;
|
||||
|
||||
public enum XpGoalTimeType
|
||||
{
|
||||
DAYS,
|
||||
HOURS,
|
||||
SHORT
|
||||
}
|
||||
@@ -75,7 +75,7 @@ class XpInfoBox extends JPanel
|
||||
private static final String HTML_TOOL_TIP_TEMPLATE =
|
||||
"<html>%s %s done<br/>"
|
||||
+ "%s %s/hr<br/>"
|
||||
+ "%s till goal lvl</html>";
|
||||
+ "%s %s</html>";
|
||||
private static final String HTML_LABEL_TEMPLATE =
|
||||
"<html><body style='color:%s'>%s<span style='color:white'>%s</span></body></html>";
|
||||
|
||||
@@ -287,13 +287,16 @@ class XpInfoBox extends JPanel
|
||||
progressBar.setPositions(Collections.emptyList());
|
||||
}
|
||||
|
||||
XpProgressBarLabel tooltipLabel = xpTrackerConfig.progressBarTooltipLabel();
|
||||
|
||||
progressBar.setToolTipText(String.format(
|
||||
HTML_TOOL_TIP_TEMPLATE,
|
||||
xpSnapshotSingle.getActionsInSession(),
|
||||
xpSnapshotSingle.getActionType().getLabel(),
|
||||
xpSnapshotSingle.getActionsPerHour(),
|
||||
xpSnapshotSingle.getActionType().getLabel(),
|
||||
xpSnapshotSingle.getTimeTillGoal()));
|
||||
tooltipLabel.getValueFunc().apply(xpSnapshotSingle),
|
||||
tooltipLabel == XpProgressBarLabel.PERCENTAGE ? "of goal" : "till goal lvl"));
|
||||
|
||||
progressBar.setDimmed(skillPaused);
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ public enum XpProgressBarLabel
|
||||
{
|
||||
PERCENTAGE((snap) -> TWO_DECIMAL_FORMAT.format(snap.getSkillProgressToGoal()) + "%"),
|
||||
TIME_TO_LEVEL(XpSnapshotSingle::getTimeTillGoal),
|
||||
HOURS_TO_LEVEL(XpSnapshotSingle::getTimeTillGoalHours)
|
||||
;
|
||||
|
||||
private final Function<XpSnapshotSingle, String> valueFunc;
|
||||
|
||||
@@ -44,5 +44,6 @@ class XpSnapshotSingle
|
||||
private int actionsRemainingToGoal;
|
||||
private int actionsPerHour;
|
||||
private String timeTillGoal;
|
||||
private String timeTillGoalHours;
|
||||
private String timeTillGoalShort;
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ class XpStateSingle
|
||||
return (getXpRemaining() * seconds) / xpGained;
|
||||
}
|
||||
|
||||
private String getTimeTillLevel()
|
||||
private String getTimeTillLevel(XpGoalTimeType goalTimeType)
|
||||
{
|
||||
long remainingSeconds = getSecondsTillLevel();
|
||||
if (remainingSeconds < 0)
|
||||
@@ -157,49 +157,44 @@ class XpStateSingle
|
||||
|
||||
long durationDays = remainingSeconds / (24 * 60 * 60);
|
||||
long durationHours = (remainingSeconds % (24 * 60 * 60)) / (60 * 60);
|
||||
long durationHoursTotal = remainingSeconds / (60 * 60);
|
||||
long durationMinutes = (remainingSeconds % (60 * 60)) / 60;
|
||||
long durationSeconds = remainingSeconds % 60;
|
||||
|
||||
if (durationDays > 1)
|
||||
switch (goalTimeType)
|
||||
{
|
||||
return String.format("%d days %02d:%02d:%02d", durationDays, durationHours, durationMinutes, durationSeconds);
|
||||
}
|
||||
else if (durationDays == 1)
|
||||
{
|
||||
return String.format("1 day %02d:%02d:%02d", durationHours, durationMinutes, durationSeconds);
|
||||
}
|
||||
case DAYS:
|
||||
if (durationDays > 1)
|
||||
{
|
||||
return String.format("%d days %02d:%02d:%02d", durationDays, durationHours, durationMinutes, durationSeconds);
|
||||
}
|
||||
else if (durationDays == 1)
|
||||
{
|
||||
return String.format("1 day %02d:%02d:%02d", durationHours, durationMinutes, durationSeconds);
|
||||
}
|
||||
case HOURS:
|
||||
if (durationHoursTotal > 1)
|
||||
{
|
||||
return String.format("%d hours %02d:%02d", durationHoursTotal, durationMinutes, durationSeconds);
|
||||
}
|
||||
else if (durationHoursTotal == 1)
|
||||
{
|
||||
return String.format("1 hour %02d:%02d", durationMinutes, durationSeconds);
|
||||
}
|
||||
case SHORT:
|
||||
default:
|
||||
// durationDays = 0 or durationHoursTotal = 0 or goalTimeType = SHORT if we got here.
|
||||
// return time remaining in hh:mm:ss or mm:ss format where hh can be > 24
|
||||
if (durationHoursTotal > 0)
|
||||
{
|
||||
return String.format("%02d:%02d:%02d", durationHoursTotal, durationMinutes, durationSeconds);
|
||||
}
|
||||
|
||||
// durationDays = 0 if we got here.
|
||||
// return time remaining in hh:mm:ss or mm:ss format
|
||||
return getTimeTillLevelShort();
|
||||
// Minutes and seconds will always be present
|
||||
return String.format("%02d:%02d", durationMinutes, durationSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
// Minutes and seconds will always be present
|
||||
return String.format("%02d:%02d", durationMinutes, durationSeconds);
|
||||
}
|
||||
|
||||
|
||||
int getXpHr()
|
||||
{
|
||||
return toHourly(xpGained);
|
||||
@@ -298,8 +293,9 @@ class XpStateSingle
|
||||
.actionsInSession(getXpAction(actionType).getActions())
|
||||
.actionsRemainingToGoal(getActionsRemaining())
|
||||
.actionsPerHour(getActionsHr())
|
||||
.timeTillGoal(getTimeTillLevel())
|
||||
.timeTillGoalShort(getTimeTillLevelShort())
|
||||
.timeTillGoal(getTimeTillLevel(XpGoalTimeType.DAYS))
|
||||
.timeTillGoalHours(getTimeTillLevel(XpGoalTimeType.HOURS))
|
||||
.timeTillGoalShort(getTimeTillLevel(XpGoalTimeType.SHORT))
|
||||
.startGoalXp(startLevelExp)
|
||||
.endGoalXp(endLevelExp)
|
||||
.build();
|
||||
|
||||
@@ -180,6 +180,17 @@ public interface XpTrackerConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
position = 12,
|
||||
keyName = "progressBarTooltipLabel",
|
||||
name = "Tooltip label",
|
||||
description = "Configures the info box progress bar tooltip to show Time to goal or percentage complete"
|
||||
)
|
||||
default XpProgressBarLabel progressBarTooltipLabel()
|
||||
{
|
||||
return XpProgressBarLabel.TIME_TO_LEVEL;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 13,
|
||||
keyName = "prioritizeRecentXpSkills",
|
||||
name = "Move recently trained skills to top",
|
||||
description = "Configures whether skills should be organized by most recently gained xp"
|
||||
|
||||
Reference in New Issue
Block a user