xptracker: add option to reset per hour rates

This commit is contained in:
James Shelton
2021-05-08 00:10:06 +01:00
committed by Adam
parent 4c0abc4511
commit 8a5a0f88f9
6 changed files with 103 additions and 26 deletions

View File

@@ -30,6 +30,7 @@ import lombok.Data;
class XpAction
{
private int actions = 0;
private int actionsSinceReset = 0;
private boolean actionsHistoryInitialized = false;
private int[] actionExps = new int[10];
private int actionExpIndex = 0;

View File

@@ -135,6 +135,10 @@ class XpInfoBox extends JPanel
final JMenuItem resetOthers = new JMenuItem("Reset others");
resetOthers.addActionListener(e -> xpTrackerPlugin.resetOtherSkillState(skill));
// Create reset per hour menu
final JMenuItem resetPerHour = new JMenuItem("Reset/hr");
resetPerHour.addActionListener(e -> xpTrackerPlugin.resetSkillPerHourState(skill));
// Create reset others menu
pauseSkill.addActionListener(e -> xpTrackerPlugin.pauseSkill(skill, !paused));
@@ -144,6 +148,7 @@ class XpInfoBox extends JPanel
popupMenu.add(openXpTracker);
popupMenu.add(reset);
popupMenu.add(resetOthers);
popupMenu.add(resetPerHour);
popupMenu.add(pauseSkill);
popupMenu.add(canvasItem);
popupMenu.addPopupMenuListener(new PopupMenuListener()

View File

@@ -90,6 +90,10 @@ class XpPanel extends PluginPanel
final JMenuItem reset = new JMenuItem("Reset All");
reset.addActionListener(e -> xpTrackerPlugin.resetAndInitState());
// Create reset all per hour menu
final JMenuItem resetPerHour = new JMenuItem("Reset All/hr");
resetPerHour.addActionListener(e -> xpTrackerPlugin.resetAllSkillsPerHourState());
// Create pause all menu
final JMenuItem pauseAll = new JMenuItem("Pause All");
pauseAll.addActionListener(e -> xpTrackerPlugin.pauseAllSkills(true));
@@ -104,6 +108,7 @@ class XpPanel extends PluginPanel
popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5));
popupMenu.add(openXpTracker);
popupMenu.add(reset);
popupMenu.add(resetPerHour);
popupMenu.add(pauseAll);
popupMenu.add(unpauseAll);
overallPanel.setComponentPopupMenu(popupMenu);

View File

@@ -32,7 +32,7 @@ import net.runelite.api.Skill;
/**
* Internal state for the XpTrackerPlugin
*
* <p>
* Note: This class's operations are not currently synchronized.
* It is intended to be called by the XpTrackerPlugin on the client thread.
*/
@@ -53,7 +53,8 @@ class XpState
/**
* Resets a single skill
* @param skill Skill to reset
*
* @param skill Skill to reset
* @param currentXp Current XP to set to, if unknown set to -1
*/
void resetSkill(Skill skill, long currentXp)
@@ -62,15 +63,26 @@ class XpState
xpSkills.put(skill, new XpStateSingle(skill, currentXp));
}
/**
* Resets the per hour rates of a single skill
*
* @param skill Skill to reset per hour rates
*/
void resetSkillPerHour(Skill skill)
{
xpSkills.get(skill).resetPerHour();
}
/**
* Updates a skill with the current known XP.
* When the result of this operation is XpUpdateResult.UPDATED, the UI should be updated accordingly.
* This is to distinguish events that reload all the skill's current values (such as world hopping)
* and also first-login when the skills are not initialized (the start XP will be -1 in this case).
* @param skill Skill to update
* @param currentXp Current known XP for this skill
*
* @param skill Skill to update
* @param currentXp Current known XP for this skill
* @param goalStartXp Possible XP start goal
* @param goalEndXp Possible XP end goal
* @param goalEndXp Possible XP end goal
* @return Whether or not the skill has been initialized, there was no change, or it has been updated
*/
XpUpdateResult updateSkill(Skill skill, long currentXp, int goalStartXp, int goalEndXp)
@@ -92,7 +104,7 @@ class XpState
else
{
long startXp = state.getStartXp();
int gainedXp = state.getXpGained();
int gainedXp = state.getTotalXpGained();
if (startXp + gainedXp > currentXp)
{
@@ -119,8 +131,9 @@ class XpState
/**
* Updates skill with average actions based on currently interacted NPC.
* @param skill experience gained skill
* @param npc currently interacted NPC
*
* @param skill experience gained skill
* @param npc currently interacted NPC
* @param npcHealth health of currently interacted NPC
*/
void updateNpcExperience(Skill skill, NPC npc, Integer npcHealth, int xpModifier)
@@ -161,8 +174,9 @@ class XpState
/**
* Update number of actions performed for skill if last interacted NPC died.
* (eg. amount of kills in this case)
* @param skill skill to update actions for
* @param npc npc that just died
*
* @param skill skill to update actions for
* @param npc npc that just died
* @param npcHealth max health of npc that just died
* @return UPDATED in case new kill was successfully added
*/
@@ -170,13 +184,13 @@ class XpState
{
XpStateSingle state = getSkill(skill);
if (state.getXpGained() <= 0 || npcHealth == null || npc != interactedNPC)
if (state.getXpGainedSinceReset() <= 0 || npcHealth == null || npc != interactedNPC)
{
return XpUpdateResult.NO_CHANGE;
}
final XpAction xpAction = state.getXpAction(XpActionType.ACTOR_HEALTH);
xpAction.setActions(xpAction.getActions() + 1);
xpAction.setActionsSinceReset(xpAction.getActionsSinceReset() + 1);
return xpAction.isActionsHistoryInitialized() ? XpUpdateResult.UPDATED : XpUpdateResult.NO_CHANGE;
}
@@ -188,7 +202,8 @@ class XpState
/**
* 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.
* @param skill Skill to initialize
*
* @param skill Skill to initialize
* @param currentXp Current known XP for the skill
*/
void initializeSkill(Skill skill, long currentXp)
@@ -211,6 +226,7 @@ class XpState
/**
* Obtain an immutable snapshot of the provided skill
* intended for use with the UI which operates on another thread
*
* @param skill Skill to obtain the snapshot for
* @return An immutable snapshot of the specified skill for this session since first login or last reset
*/
@@ -223,6 +239,7 @@ class XpState
/**
* Obtain an immutable snapshot of the provided skill
* intended for use with the UI which operates on another thread
*
* @return An immutable snapshot of total information for this session since first login or last reset
*/
@NonNull

View File

@@ -45,12 +45,16 @@ class XpStateSingle
private long startXp;
@Getter
private int xpGained = 0;
private int xpGainedSinceReset = 0;
private int xpGainedBeforeReset = 0;
@Setter
private XpActionType actionType = XpActionType.EXPERIENCE;
@Setter
private long skillTime = 0;
private int startLevelExp = 0;
private int endLevelExp = 0;
@@ -68,12 +72,17 @@ class XpStateSingle
long getCurrentXp()
{
return startXp + xpGained;
return startXp + getTotalXpGained();
}
int getTotalXpGained()
{
return xpGainedBeforeReset + xpGainedSinceReset;
}
private int getActionsHr()
{
return toHourly(getXpAction(actionType).getActions());
return toHourly(getXpAction(actionType).getActionsSinceReset());
}
private int toHourly(int value)
@@ -136,7 +145,7 @@ class XpStateSingle
// below will be a custom formatter that handles spans larger than 1 day
long seconds = getTimeElapsedInSeconds();
if (seconds <= 0 || xpGained <= 0)
if (seconds <= 0 || xpGainedSinceReset <= 0)
{
return -1;
}
@@ -144,7 +153,7 @@ class XpStateSingle
// 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!
return (getXpRemaining() * seconds) / xpGained;
return (getXpRemaining() * seconds) / xpGainedSinceReset;
}
private String getTimeTillLevel(XpGoalTimeType goalTimeType)
@@ -197,7 +206,22 @@ class XpStateSingle
int getXpHr()
{
return toHourly(xpGained);
return toHourly(xpGainedSinceReset);
}
void resetPerHour()
{
//reset actions per hour
for (XpAction action : actions.values())
{
action.setActions(action.getActions() + action.getActionsSinceReset());
action.setActionsSinceReset(0);
}
//reset xp per hour
xpGainedBeforeReset += xpGainedSinceReset;
xpGainedSinceReset = 0;
setSkillTime(0);
}
boolean update(long currentXp, int goalStartXp, int goalEndXp)
@@ -208,7 +232,7 @@ class XpStateSingle
return false;
}
long originalXp = xpGained + startXp;
long originalXp = getTotalXpGained() + startXp;
int actionExp = (int) (currentXp - originalXp);
// No experience gained
@@ -237,10 +261,10 @@ class XpStateSingle
}
action.setActionExpIndex((action.getActionExpIndex() + 1) % action.getActionExps().length);
action.setActions(action.getActions() + 1);
action.setActionsSinceReset(action.getActionsSinceReset() + 1);
// Calculate experience gained
xpGained = (int) (currentXp - startXp);
xpGainedSinceReset = (int) (currentXp - (startXp + xpGainedBeforeReset));
// Determine XP goals, overall has no goals
if (skill != Skill.OVERALL)
@@ -273,7 +297,7 @@ class XpStateSingle
public void tick(long delta)
{
// Don't tick skills that have not gained XP or have been reset.
if (xpGained <= 0)
if (xpGainedSinceReset <= 0)
{
return;
}
@@ -285,12 +309,12 @@ class XpStateSingle
return XpSnapshotSingle.builder()
.startLevel(Experience.getLevelForXp(startLevelExp))
.endLevel(Experience.getLevelForXp(endLevelExp))
.xpGainedInSession(xpGained)
.xpGainedInSession(getTotalXpGained())
.xpRemainingToGoal(getXpRemaining())
.xpPerHour(getXpHr())
.skillProgressToGoal(getSkillProgress())
.actionType(actionType)
.actionsInSession(getXpAction(actionType).getActions())
.actionsInSession(getXpAction(actionType).getActions() + getXpAction(actionType).getActionsSinceReset())
.actionsRemainingToGoal(getActionsRemaining())
.actionsPerHour(getActionsHr())
.timeTillGoal(getTimeTillLevel(XpGoalTimeType.DAYS))

View File

@@ -323,6 +323,7 @@ public class XpTrackerPlugin extends Plugin
/**
* Reset an individual skill with the client's current known state of the skill
* Will also clear the skill from the UI.
*
* @param skill Skill to reset
*/
void resetSkillState(Skill skill)
@@ -335,6 +336,7 @@ public class XpTrackerPlugin extends Plugin
/**
* Reset all skills except for the one provided
*
* @param skill Skill to ignore during reset
*/
void resetOtherSkillState(Skill skill)
@@ -349,6 +351,29 @@ public class XpTrackerPlugin extends Plugin
}
}
/**
* Reset the xp gained since last reset of the skill
* Does not clear the skill from the UI.
*
* @param skill Skill to reset per hour rate
*/
void resetSkillPerHourState(Skill skill)
{
xpState.resetSkillPerHour(skill);
}
/**
* Reset the xp gained since last reset of all skills including OVERALL
* Does not clear the UI.
*/
void resetAllSkillsPerHourState()
{
for (Skill skill : Skill.values())
{
resetSkillPerHourState(skill);
}
}
@Subscribe
public void onStatChanged(StatChanged statChanged)
{
@@ -377,7 +402,7 @@ public class XpTrackerPlugin extends Plugin
final Actor interacting = client.getLocalPlayer().getInteracting();
if (interacting instanceof NPC && COMBAT.contains(skill))
{
final int xpModifier = worldSetToType(client.getWorldType()).modifier(client);;
final int xpModifier = worldSetToType(client.getWorldType()).modifier(client);
final NPC npc = (NPC) interacting;
xpState.updateNpcExperience(skill, npc, npcManager.getHealth(npc.getId()), xpModifier);
}