runelite-client: add central skill icon cache
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.game;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Skill;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class SkillIconManager
|
||||
{
|
||||
private final BufferedImage[] imgCache = new BufferedImage[Skill.values().length];
|
||||
|
||||
public BufferedImage getSkillImage(Skill skill)
|
||||
{
|
||||
int skillIdx = skill.ordinal();
|
||||
BufferedImage skillImage = null;
|
||||
|
||||
if (imgCache[skillIdx] != null)
|
||||
{
|
||||
return imgCache[skillIdx];
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
String skillIconPath = "/skill_icons/" + skill.getName().toLowerCase() + ".png";
|
||||
log.debug("Loading skill icon from {}", skillIconPath);
|
||||
skillImage = ImageIO.read(SkillIconManager.class.getResourceAsStream(skillIconPath));
|
||||
imgCache[skillIdx] = skillImage;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.debug("Error Loading skill icons {}", e);
|
||||
}
|
||||
|
||||
return skillImage;
|
||||
}
|
||||
}
|
||||
@@ -28,15 +28,13 @@ import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
@@ -46,8 +44,6 @@ import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
@Slf4j
|
||||
class BoostsOverlay extends Overlay
|
||||
{
|
||||
private final BufferedImage[] imgCache = new BufferedImage[Skill.values().length - 1];
|
||||
|
||||
@Getter
|
||||
private final BoostIndicator[] indicators = new BoostIndicator[Skill.values().length - 1];
|
||||
|
||||
@@ -58,6 +54,9 @@ class BoostsOverlay extends Overlay
|
||||
@Inject
|
||||
private BoostsPlugin plugin;
|
||||
|
||||
@Inject
|
||||
private SkillIconManager iconManager;
|
||||
|
||||
private PanelComponent panelComponent;
|
||||
|
||||
@Inject
|
||||
@@ -100,7 +99,7 @@ class BoostsOverlay extends Overlay
|
||||
{
|
||||
if (indicators[skill.ordinal()] == null)
|
||||
{
|
||||
BoostIndicator indicator = new BoostIndicator(skill, getSkillImage(skill), client, config);
|
||||
BoostIndicator indicator = new BoostIndicator(skill, iconManager.getSkillImage(skill), client, config);
|
||||
indicators[skill.ordinal()] = indicator;
|
||||
infoBoxManager.addInfoBox(indicator);
|
||||
}
|
||||
@@ -146,29 +145,4 @@ class BoostsOverlay extends Overlay
|
||||
return new Color(238, 51, 51);
|
||||
|
||||
}
|
||||
|
||||
private BufferedImage getSkillImage(Skill skill)
|
||||
{
|
||||
int skillIdx = skill.ordinal();
|
||||
BufferedImage skillImage = null;
|
||||
|
||||
if (imgCache[skillIdx] != null)
|
||||
{
|
||||
return imgCache[skillIdx];
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
String skillIconPath = "/skill_icons/" + skill.getName().toLowerCase() + ".png";
|
||||
log.debug("Loading skill icon from {}", skillIconPath);
|
||||
skillImage = ImageIO.read(BoostsOverlay.class.getResourceAsStream(skillIconPath));
|
||||
imgCache[skillIdx] = skillImage;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.debug("Error Loading skill icons {}", e);
|
||||
}
|
||||
|
||||
return skillImage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import com.google.common.collect.Sets;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.google.inject.Binder;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
@@ -37,7 +36,6 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
@@ -73,9 +71,6 @@ public class MotherlodePlugin extends Plugin
|
||||
private static final Set<Integer> MINE_SPOTS = Sets.newHashSet(ORE_VEIN_26661, ORE_VEIN_26662, ORE_VEIN_26663, ORE_VEIN_26664);
|
||||
private static final Set<Integer> ROCK_OBSTACLES = Sets.newHashSet(ROCKFALL, ROCKFALL_26680);
|
||||
|
||||
@Getter
|
||||
private BufferedImage mineIcon;
|
||||
|
||||
@Inject
|
||||
private MotherlodeOverlay overlay;
|
||||
|
||||
@@ -113,12 +108,6 @@ public class MotherlodePlugin extends Plugin
|
||||
return Arrays.asList(overlay, rocksOverlay, motherlodeSackOverlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
mineIcon = ImageIO.read(MotherlodePlugin.class.getResourceAsStream("/skill_icons/mining.png"));
|
||||
}
|
||||
|
||||
public MotherlodeSession getSession()
|
||||
{
|
||||
return session;
|
||||
|
||||
@@ -29,13 +29,16 @@ import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameObject;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.api.WallObject;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
@@ -49,14 +52,18 @@ class MotherlodeRocksOverlay extends Overlay
|
||||
private final MotherlodePlugin plugin;
|
||||
private final MotherlodeConfig config;
|
||||
|
||||
private final BufferedImage miningIcon;
|
||||
|
||||
@Inject
|
||||
MotherlodeRocksOverlay(Client client, MotherlodePlugin plugin, MotherlodeConfig config)
|
||||
MotherlodeRocksOverlay(Client client, MotherlodePlugin plugin, MotherlodeConfig config, SkillIconManager iconManager)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
|
||||
miningIcon = iconManager.getSkillImage(Skill.MINING);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,11 +105,11 @@ class MotherlodeRocksOverlay extends Overlay
|
||||
|
||||
private void renderVein(Graphics2D graphics, WallObject vein)
|
||||
{
|
||||
Point canvasLoc = Perspective.getCanvasImageLocation(client, graphics, vein.getLocalLocation(), plugin.getMineIcon(), 150);
|
||||
Point canvasLoc = Perspective.getCanvasImageLocation(client, graphics, vein.getLocalLocation(), miningIcon, 150);
|
||||
|
||||
if (canvasLoc != null)
|
||||
{
|
||||
graphics.drawImage(plugin.getMineIcon(), canvasLoc.getX(), canvasLoc.getY(), null);
|
||||
graphics.drawImage(miningIcon, canvasLoc.getX(), canvasLoc.getY(), null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,17 +32,15 @@ import java.awt.Stroke;
|
||||
import java.awt.geom.Arc2D;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Experience;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
@@ -56,6 +54,9 @@ public class XpGlobesOverlay extends Overlay
|
||||
private final XpGlobesPlugin plugin;
|
||||
private final XpGlobesConfig config;
|
||||
|
||||
@Inject
|
||||
private SkillIconManager iconManager;
|
||||
|
||||
private static final int DEFAULT_CIRCLE_WIDTH = 40;
|
||||
private static final int DEFAULT_CIRCLE_HEIGHT = 40;
|
||||
private static final int MINIMUM_STEP_WIDTH = DEFAULT_CIRCLE_WIDTH + 10;
|
||||
@@ -69,8 +70,6 @@ public class XpGlobesOverlay extends Overlay
|
||||
|
||||
private static final int DEFAULT_START_Y = 10;
|
||||
|
||||
private final BufferedImage[] imgCache = new BufferedImage[Skill.values().length - 1];
|
||||
|
||||
private static final int TOOLTIP_RECT_SIZE_X = 150;
|
||||
|
||||
@Inject
|
||||
@@ -171,7 +170,7 @@ public class XpGlobesOverlay extends Overlay
|
||||
|
||||
private void drawSkillImage(Graphics2D graphics, XpGlobe xpGlobe, int x, int y)
|
||||
{
|
||||
BufferedImage skillImage = getSkillImage(xpGlobe);
|
||||
BufferedImage skillImage = iconManager.getSkillImage(xpGlobe.getSkill());
|
||||
|
||||
if (skillImage == null)
|
||||
{
|
||||
@@ -186,31 +185,6 @@ public class XpGlobesOverlay extends Overlay
|
||||
);
|
||||
}
|
||||
|
||||
private BufferedImage getSkillImage(XpGlobe xpGlobe)
|
||||
{
|
||||
int skillIdx = xpGlobe.getSkill().ordinal();
|
||||
BufferedImage skillImage = null;
|
||||
|
||||
if (imgCache[skillIdx] != null)
|
||||
{
|
||||
return imgCache[skillIdx];
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
String skillIconPath = "/skill_icons/" + xpGlobe.getSkillName().toLowerCase() + ".png";
|
||||
log.debug("Loading skill icon from {}", skillIconPath);
|
||||
skillImage = ImageIO.read(XpGlobesOverlay.class.getResourceAsStream(skillIconPath));
|
||||
imgCache[skillIdx] = skillImage;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.debug("Error Loading skill icons {}", e);
|
||||
}
|
||||
|
||||
return skillImage;
|
||||
}
|
||||
|
||||
private void drawTooltipIfMouseover(Graphics2D graphics, java.awt.Point parent, XpGlobe mouseOverSkill, Ellipse2D drawnGlobe)
|
||||
{
|
||||
Point mouse = client.getMouseCanvasPosition();
|
||||
|
||||
@@ -29,7 +29,6 @@ import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridLayout;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
@@ -41,13 +40,19 @@ import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
|
||||
@Slf4j
|
||||
class XpInfoBox extends JPanel
|
||||
{
|
||||
|
||||
private static final Color[] PROGRESS_COLORS = new Color[] { Color.RED, Color.YELLOW, Color.GREEN };
|
||||
private static final Color[] PROGRESS_COLORS = new Color[]
|
||||
{
|
||||
Color.RED, Color.YELLOW, Color.GREEN
|
||||
};
|
||||
|
||||
private final Client client;
|
||||
private final JPanel panel;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final SkillXPInfo xpInfo;
|
||||
|
||||
@@ -56,10 +61,8 @@ class XpInfoBox extends JPanel
|
||||
private final JLabel xpGained = new JLabel();
|
||||
private final JLabel actionsHr = new JLabel();
|
||||
private final JLabel actions = new JLabel();
|
||||
private final Client client;
|
||||
private final JPanel panel;
|
||||
|
||||
XpInfoBox(Client client, JPanel panel, SkillXPInfo xpInfo) throws IOException
|
||||
XpInfoBox(Client client, JPanel panel, SkillXPInfo xpInfo, SkillIconManager iconManager) throws IOException
|
||||
{
|
||||
this.client = client;
|
||||
this.panel = panel;
|
||||
@@ -73,8 +76,7 @@ class XpInfoBox extends JPanel
|
||||
container.setLayout(new BorderLayout(3, 3));
|
||||
|
||||
// Create skill/reset icon
|
||||
final String skillIcon = "/skill_icons/" + xpInfo.getSkill().getName().toLowerCase() + ".png";
|
||||
final JButton resetIcon = new JButton(new ImageIcon(ImageIO.read(getClass().getResourceAsStream(skillIcon))));
|
||||
final JButton resetIcon = new JButton(new ImageIcon(iconManager.getSkillImage(xpInfo.getSkill())));
|
||||
resetIcon.setToolTipText("Reset " + xpInfo.getSkill().getName() + " tracker");
|
||||
resetIcon.setPreferredSize(new Dimension(64, 64));
|
||||
resetIcon.addActionListener(e -> reset());
|
||||
@@ -143,7 +145,7 @@ class XpInfoBox extends JPanel
|
||||
final int progress = xpInfo.getSkillProgress();
|
||||
|
||||
progressBar.setValue(progress);
|
||||
progressBar.setBackground(interpolateColors(PROGRESS_COLORS, (double)progress / 100d));
|
||||
progressBar.setBackground(interpolateColors(PROGRESS_COLORS, (double) progress / 100d));
|
||||
|
||||
progressBar.setToolTipText("<html>"
|
||||
+ XpPanel.formatLine(xpInfo.getXpRemaining(), "xp remaining")
|
||||
@@ -158,10 +160,13 @@ class XpInfoBox extends JPanel
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Interpolate between array of colors using Normal (Gaussian) distribution
|
||||
* @see <a href="https://en.wikipedia.org/wiki/Normal_distribution}">Normal distribution on Wikipedia</a>
|
||||
* Interpolate between array of colors using Normal (Gaussian)
|
||||
* distribution
|
||||
*
|
||||
* @see
|
||||
* <a href="https://en.wikipedia.org/wiki/Normal_distribution}">Normal
|
||||
* distribution on Wikipedia</a>
|
||||
* @param colors array of colors
|
||||
* @param x distribution factor
|
||||
* @return interpolated color
|
||||
@@ -170,7 +175,7 @@ class XpInfoBox extends JPanel
|
||||
{
|
||||
double r = 0.0, g = 0.0, b = 0.0;
|
||||
double total = 0.0;
|
||||
double step = 1.0 / (double)(colors.length - 1);
|
||||
double step = 1.0 / (double) (colors.length - 1);
|
||||
double mu = 0.0;
|
||||
double sigma2 = 0.035;
|
||||
|
||||
@@ -192,6 +197,6 @@ class XpInfoBox extends JPanel
|
||||
b += color.getBlue() * percent / total;
|
||||
}
|
||||
|
||||
return new Color((int)r, (int)g, (int)b);
|
||||
return new Color((int) r, (int) g, (int) b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import javax.swing.SwingUtilities;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Skill;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
import net.runelite.client.ui.PluginPanel;
|
||||
|
||||
@Slf4j
|
||||
@@ -48,8 +49,7 @@ class XpPanel extends PluginPanel
|
||||
private final JLabel totalXpGained = new JLabel();
|
||||
private final JLabel totalXpHr = new JLabel();
|
||||
|
||||
|
||||
XpPanel(Client client)
|
||||
XpPanel(Client client, SkillIconManager iconManager)
|
||||
{
|
||||
super();
|
||||
|
||||
@@ -90,7 +90,7 @@ class XpPanel extends PluginPanel
|
||||
break;
|
||||
}
|
||||
|
||||
infoBoxes.put(skill, new XpInfoBox(client, infoBoxPanel, new SkillXPInfo(skill)));
|
||||
infoBoxes.put(skill, new XpInfoBox(client, infoBoxPanel, new SkillXPInfo(skill), iconManager));
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
|
||||
@@ -39,6 +39,7 @@ import net.runelite.api.Player;
|
||||
import net.runelite.api.events.ExperienceChanged;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.ClientUI;
|
||||
@@ -62,7 +63,10 @@ public class XpTrackerPlugin extends Plugin
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
ScheduledExecutorService executor;
|
||||
private SkillIconManager skillIconManager;
|
||||
|
||||
@Inject
|
||||
private ScheduledExecutorService executor;
|
||||
|
||||
private NavigationButton navButton;
|
||||
private XpPanel xpPanel;
|
||||
@@ -86,7 +90,7 @@ public class XpTrackerPlugin extends Plugin
|
||||
log.warn("Error looking up worlds list", e);
|
||||
}
|
||||
|
||||
xpPanel = new XpPanel(client);
|
||||
xpPanel = new XpPanel(client, skillIconManager);
|
||||
navButton = new NavigationButton(
|
||||
"XP Tracker",
|
||||
ImageIO.read(getClass().getResourceAsStream("xp.png")),
|
||||
|
||||
Reference in New Issue
Block a user