Added xp/hr tracker
This commit is contained in:
@@ -51,6 +51,7 @@ import net.runelite.client.plugins.opponentinfo.OpponentInfo;
|
|||||||
import net.runelite.client.plugins.pestcontrol.PestControl;
|
import net.runelite.client.plugins.pestcontrol.PestControl;
|
||||||
import net.runelite.client.plugins.runecraft.Runecraft;
|
import net.runelite.client.plugins.runecraft.Runecraft;
|
||||||
import net.runelite.client.plugins.xpglobes.XpGlobes;
|
import net.runelite.client.plugins.xpglobes.XpGlobes;
|
||||||
|
import net.runelite.client.plugins.xptracker.XPTracker;
|
||||||
import net.runelite.client.plugins.xtea.Xtea;
|
import net.runelite.client.plugins.xtea.Xtea;
|
||||||
import net.runelite.client.plugins.zulrah.Zulrah;
|
import net.runelite.client.plugins.zulrah.Zulrah;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -90,6 +91,7 @@ public class PluginManager
|
|||||||
plugins.add(new XpGlobes());
|
plugins.add(new XpGlobes());
|
||||||
plugins.add(new CombatNotifier());
|
plugins.add(new CombatNotifier());
|
||||||
plugins.add(new JewelryCount());
|
plugins.add(new JewelryCount());
|
||||||
|
plugins.add(new XPTracker());
|
||||||
plugins.add(new ExaminePlugin());
|
plugins.add(new ExaminePlugin());
|
||||||
|
|
||||||
if (RuneLite.getOptions().has("developer-mode"))
|
if (RuneLite.getOptions().has("developer-mode"))
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Cameron <moberg@tuta.io>
|
||||||
|
* 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.api.Skill;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
public class SkillXPInfo
|
||||||
|
{
|
||||||
|
private Skill skill;
|
||||||
|
private Instant skillTimeStart = null;
|
||||||
|
private int xpGained = 0;
|
||||||
|
private int loginXp = 0;
|
||||||
|
|
||||||
|
public SkillXPInfo(int loginXp, Skill skill)
|
||||||
|
{
|
||||||
|
this.skill = skill;
|
||||||
|
this.loginXp = loginXp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getXpHr()
|
||||||
|
{
|
||||||
|
long timeElapsedInSeconds = Duration.between(
|
||||||
|
skillTimeStart, Instant.now()).getSeconds();
|
||||||
|
return (int) ((1.0 / (timeElapsedInSeconds / 3600.0)) * xpGained);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset(int loginXp)
|
||||||
|
{
|
||||||
|
xpGained = 0;
|
||||||
|
this.loginXp = loginXp;
|
||||||
|
skillTimeStart = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(int currentXp)
|
||||||
|
{
|
||||||
|
xpGained = currentXp - loginXp;
|
||||||
|
if (skillTimeStart == null)
|
||||||
|
skillTimeStart = Instant.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant getSkillTimeStart()
|
||||||
|
{
|
||||||
|
return skillTimeStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getXpGained()
|
||||||
|
{
|
||||||
|
return xpGained;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLoginXp()
|
||||||
|
{
|
||||||
|
return loginXp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Skill getSkill()
|
||||||
|
{
|
||||||
|
return this.skill;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Cameron <moberg@tuta.io>
|
||||||
|
* 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.api.Client;
|
||||||
|
import net.runelite.api.Skill;
|
||||||
|
import net.runelite.client.RuneLite;
|
||||||
|
import net.runelite.client.ui.PluginPanel;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class XPPanel extends PluginPanel
|
||||||
|
{
|
||||||
|
private static final Client client = RuneLite.getClient();
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(XPPanel.class);
|
||||||
|
private Map<Skill, JPanel> labelMap = new HashMap<>();
|
||||||
|
private final XPTracker xpTracker;
|
||||||
|
private JPanel statsPanel;
|
||||||
|
|
||||||
|
public XPPanel(RuneLite runelite, XPTracker xpTracker)
|
||||||
|
{
|
||||||
|
this.xpTracker = xpTracker;
|
||||||
|
|
||||||
|
setMinimumSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
|
||||||
|
setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
|
||||||
|
setSize(PANEL_WIDTH, PANEL_HEIGHT);
|
||||||
|
setVisible(true);
|
||||||
|
statsPanel = new JPanel();
|
||||||
|
statsPanel.setLayout(new GridLayout(24, 1));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (Skill skill : Skill.values())
|
||||||
|
{
|
||||||
|
if (skill == Skill.OVERALL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
JLabel skillLabel = new JLabel();
|
||||||
|
labelMap.put(skill, makeSkillPanel(skill, skillLabel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
logger.warn(null, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
JButton resetButton = new JButton("Reset All");
|
||||||
|
resetButton.setPreferredSize(new Dimension(PANEL_WIDTH, 32));
|
||||||
|
resetButton.addActionListener((ActionEvent e) ->
|
||||||
|
runelite.getExecutor().execute(this::resetAllSkillXpHr));
|
||||||
|
|
||||||
|
statsPanel.add(resetButton);
|
||||||
|
JScrollPane scroll = new JScrollPane(statsPanel);
|
||||||
|
scroll.add(statsPanel);
|
||||||
|
|
||||||
|
add(statsPanel);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JButton makeSkillResetButton(Skill skill) throws IOException
|
||||||
|
{
|
||||||
|
ImageIcon resetIcon = new ImageIcon(ImageIO.read(getClass().getResourceAsStream("reset.png")));
|
||||||
|
JButton resetButton = new JButton(resetIcon);
|
||||||
|
resetButton.setPreferredSize(new Dimension(32, 32));
|
||||||
|
resetButton.addActionListener(actionEvent -> resetSkillXpHr(skill));
|
||||||
|
return resetButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JPanel makeSkillPanel(Skill skill, JLabel levelLabel) throws IOException
|
||||||
|
{
|
||||||
|
BorderLayout borderLayout = new BorderLayout();
|
||||||
|
borderLayout.setHgap(12);
|
||||||
|
JPanel iconLevel = new JPanel(borderLayout);
|
||||||
|
iconLevel.setPreferredSize(new Dimension(PANEL_WIDTH, 32));
|
||||||
|
|
||||||
|
String skillIcon = "/skill_icons/" + skill.getName().toLowerCase() + ".png";
|
||||||
|
logger.debug("Loading skill icon from {}", skillIcon);
|
||||||
|
JLabel icon = new JLabel(new ImageIcon(ImageIO.read(XPPanel.class.getResourceAsStream(skillIcon))));
|
||||||
|
iconLevel.add(icon, BorderLayout.LINE_START);
|
||||||
|
|
||||||
|
iconLevel.add(levelLabel, BorderLayout.CENTER);
|
||||||
|
iconLevel.add(makeSkillResetButton(skill), BorderLayout.LINE_END);
|
||||||
|
|
||||||
|
return iconLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetSkillXpHr(Skill skill)
|
||||||
|
{
|
||||||
|
int skillIdx = skill.ordinal();
|
||||||
|
xpTracker.getXpInfos()[skillIdx].reset(client.getSkillExperience(skill));
|
||||||
|
statsPanel.remove(labelMap.get(skill));
|
||||||
|
statsPanel.revalidate();
|
||||||
|
statsPanel.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetAllSkillXpHr()
|
||||||
|
{
|
||||||
|
for (SkillXPInfo skillInfo : xpTracker.getXpInfos())
|
||||||
|
{
|
||||||
|
if (skillInfo != null && skillInfo.getSkillTimeStart() != null)
|
||||||
|
resetSkillXpHr(skillInfo.getSkill());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateAllSkillXpHr()
|
||||||
|
{
|
||||||
|
for (SkillXPInfo skillInfo : xpTracker.getXpInfos())
|
||||||
|
{
|
||||||
|
if (skillInfo != null && skillInfo.getSkillTimeStart() != null &&
|
||||||
|
skillInfo.getXpGained() != 0)
|
||||||
|
updateSkillXpHr(skillInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateSkillXpHr(SkillXPInfo skillXPInfo)
|
||||||
|
{
|
||||||
|
JPanel skillPanel = labelMap.get(skillXPInfo.getSkill());
|
||||||
|
JLabel xpHr = (JLabel) skillPanel.getComponent(1);
|
||||||
|
xpHr.setText(NumberFormat.getInstance().format(skillXPInfo.getXpHr()) + " xp/hr");
|
||||||
|
|
||||||
|
if (skillPanel.getParent() != statsPanel)
|
||||||
|
{
|
||||||
|
statsPanel.add(skillPanel);
|
||||||
|
statsPanel.revalidate();
|
||||||
|
statsPanel.repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Cameron <moberg@tuta.io>
|
||||||
|
* 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 com.google.common.eventbus.Subscribe;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.GameState;
|
||||||
|
import net.runelite.api.Player;
|
||||||
|
import net.runelite.api.Skill;
|
||||||
|
import net.runelite.client.RuneLite;
|
||||||
|
import net.runelite.client.events.ExperienceChanged;
|
||||||
|
import net.runelite.client.events.GameStateChanged;
|
||||||
|
import net.runelite.client.plugins.Plugin;
|
||||||
|
import net.runelite.client.ui.ClientUI;
|
||||||
|
import net.runelite.client.ui.NavigationButton;
|
||||||
|
import net.runelite.client.util.RunnableExceptionLogger;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.GraphicsEnvironment;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class XPTracker extends Plugin
|
||||||
|
{
|
||||||
|
private static final int NUMBER_OF_SKILLS = Skill.values().length - 1; //ignore overall
|
||||||
|
|
||||||
|
private final RuneLite runeLite = RuneLite.getRunelite();
|
||||||
|
private final ClientUI ui = runeLite.getGui();
|
||||||
|
private final Client client = RuneLite.getClient();
|
||||||
|
private ScheduledFuture<?> future;
|
||||||
|
|
||||||
|
private final NavigationButton navButton = new NavigationButton("XP Tracker");
|
||||||
|
private final XPPanel xpPanel = new XPPanel(runeLite, this);
|
||||||
|
private SkillXPInfo[] xpInfos = new SkillXPInfo[NUMBER_OF_SKILLS];
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onGameStateChanged(GameStateChanged event)
|
||||||
|
{
|
||||||
|
if (event.getGameState() != GameState.LOGGED_IN)
|
||||||
|
xpPanel.resetAllSkillXpHr();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onXpChanged(ExperienceChanged event)
|
||||||
|
{
|
||||||
|
Skill skill = event.getSkill();
|
||||||
|
String currentUser = client.getLocalPlayer().getName();
|
||||||
|
int skillIdx = skill.ordinal();
|
||||||
|
|
||||||
|
//To catch login ExperienceChanged event.
|
||||||
|
if (xpInfos[skillIdx] != null)
|
||||||
|
{
|
||||||
|
xpInfos[skillIdx].update(client.getSkillExperience(skill));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xpInfos[skillIdx] = new SkillXPInfo(client.getSkillExperience(skill),
|
||||||
|
skill);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setPluginPanel(ActionEvent e)
|
||||||
|
{
|
||||||
|
ui.expand(xpPanel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void startUp() throws Exception
|
||||||
|
{
|
||||||
|
navButton.getButton().addActionListener(this::setPluginPanel);
|
||||||
|
|
||||||
|
navButton.getButton().setText("XP");
|
||||||
|
ui.getNavigationPanel().addNavigation(navButton);
|
||||||
|
|
||||||
|
ScheduledExecutorService executor = RuneLite.getRunelite().getExecutor();
|
||||||
|
future = executor.scheduleAtFixedRate(RunnableExceptionLogger.wrap(
|
||||||
|
xpPanel::updateAllSkillXpHr), 0, 600, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
|
Font font = Font.createFont(Font.TRUETYPE_FONT, getClass().getResourceAsStream("/runescape.ttf"));
|
||||||
|
font = font.deriveFont(Font.BOLD, 16);
|
||||||
|
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||||
|
ge.registerFont(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void shutDown() throws Exception
|
||||||
|
{
|
||||||
|
future.cancel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SkillXPInfo[] getXpInfos()
|
||||||
|
{
|
||||||
|
return xpInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
Reference in New Issue
Block a user