Merge remote-tracking branch 'runelite/master' into ready-set-action

Conflicts:
	.gitignore
	cache-client/pom.xml
	cache-updater/pom.xml
	cache/pom.xml
	cache/src/main/java/net/runelite/cache/definitions/loaders/ParamLoader.java
	deobfuscator/src/main/java/net/runelite/deob/clientver/ClientVersion.java
	http-api/pom.xml
	http-service/pom.xml
	http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java
	pom.xml
	protocol-api/pom.xml
	protocol/pom.xml
	runelite-api/pom.xml
	runelite-api/src/main/java/net/runelite/api/Client.java
	runelite-client/pom.xml
	runelite-client/src/main/java/net/runelite/client/RuneLite.java
	runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java
	runelite-client/src/main/java/net/runelite/client/config/RuneLiteConfig.java
	runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java
	runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraConfig.java
	runelite-client/src/main/java/net/runelite/client/plugins/camera/CameraPlugin.java
	runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonConfig.java
	runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java
	runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java
	runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPlugin.java
	runelite-client/src/main/java/net/runelite/client/plugins/config/HotkeyButton.java
	runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java
	runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java
	runelite-client/src/main/java/net/runelite/client/plugins/friendnotes/FriendNotesPlugin.java
	runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java
	runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java
	runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPlugin.java
	runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java
	runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java
	runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java
	runelite-client/src/main/java/net/runelite/client/plugins/musicindicator/MusicIndicatorPlugin.java
	runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java
	runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java
	runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java
	runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingPlugin.java
	runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java
	runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java
	runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java
	runelite-client/src/main/java/net/runelite/client/rs/CountingInputStream.java
	runelite-client/src/main/java/net/runelite/client/ui/FatalErrorDialog.java
	runelite-client/src/main/java/net/runelite/client/ui/SplashScreen.java
	runelite-client/src/main/java/net/runelite/client/util/CountingInputStream.java
	runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java
	runelite-client/src/main/java/net/runelite/client/util/SwingUtil.java
	runelite-client/src/main/resources/net/runelite/client/runelite.properties
	runelite-client/src/main/resources/npc_health.json
	runelite-client/src/test/java/net/runelite/client/plugins/hiscore/HiscorePanelTest.java
	runelite-client/src/test/java/net/runelite/client/plugins/raids/RaidsPluginTest.java
	runelite-script-assembler-plugin/pom.xml
This commit is contained in:
Owain van Brakel
2020-01-09 19:59:46 +01:00
118 changed files with 1696 additions and 918 deletions

View File

@@ -153,7 +153,7 @@ public class ChatMessageManager
messageNode.setName(ColorUtil.wrapWithColorTag(messageNode.getName(), usernameColor));
}
String sender = chatMessage.getSender();
String sender = messageNode.getSender();
if (senderColor != null && !Strings.isNullOrEmpty(sender))
{
messageNode.setSender(ColorUtil.wrapWithColorTag(sender, senderColor));

View File

@@ -29,9 +29,11 @@ import net.runelite.api.Constants;
import net.runelite.client.Notifier;
import net.runelite.client.ui.ContainableFrame;
@ConfigGroup("runelite")
@ConfigGroup(RuneLiteConfig.GROUP_NAME)
public interface RuneLiteConfig extends Config
{
String GROUP_NAME = "runelite";
@ConfigTitleSection(
keyName = "uiTitle",
name = "User interface",

View File

@@ -880,19 +880,21 @@ public class TabInterface
--maxTabs;
}
if (currentTabIndex + direction >= tabManager.size() || currentTabIndex + direction < 0)
int proposedIndex = currentTabIndex + direction;
int numTabs = tabManager.size() + 1;
if (proposedIndex >= numTabs || proposedIndex < 0)
{
currentTabIndex = 0;
}
if ((tabManager.size() - (currentTabIndex + direction) >= maxTabs) && (currentTabIndex + direction > -1))
else if (numTabs - proposedIndex >= maxTabs)
{
currentTabIndex += direction;
currentTabIndex = proposedIndex;
}
else if (maxTabs < tabManager.size() && tabManager.size() - (currentTabIndex + direction) < maxTabs)
else if (maxTabs < numTabs && numTabs - proposedIndex < maxTabs)
{
// Edge case when only 1 tab displays instead of up to maxTabs when one is deleted at the end of the list
currentTabIndex += direction;
currentTabIndex = proposedIndex;
scrollTab(-1);
}
@@ -973,7 +975,7 @@ public class TabInterface
{
int y = bounds.y + MARGIN + BUTTON_HEIGHT;
if (maxTabs >= tabManager.size())
if (maxTabs > tabManager.size())
{
currentTabIndex = 0;
}
@@ -999,6 +1001,8 @@ public class TabInterface
y += TAB_HEIGHT + MARGIN;
}
updateWidget(newTab, y);
boolean hidden = !(tabManager.size() > 0);
upButton.setHidden(hidden);

View File

@@ -147,4 +147,15 @@ public interface CameraConfig extends Config
{
return false;
}
}
@ConfigItem(
keyName = "compassLook",
name = "Compass options",
description = "Adds Look South, East, and West options to the compass",
position = 10
)
default boolean compassLook()
{
return true;
}
}

View File

@@ -30,13 +30,16 @@ import com.google.inject.Inject;
import com.google.inject.Provides;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import javax.swing.SwingUtilities;
import net.runelite.api.Client;
import net.runelite.api.MenuEntry;
import net.runelite.api.MenuOpcode;
import net.runelite.api.ScriptID;
import net.runelite.api.VarPlayer;
import net.runelite.api.events.ClientTick;
import net.runelite.api.events.FocusChanged;
import net.runelite.api.events.MenuEntryAdded;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager;
@@ -65,6 +68,10 @@ public class CameraPlugin extends Plugin implements KeyListener, MouseListener
*/
private static final int INNER_ZOOM_LIMIT = 1004;
private static final int DEFAULT_ZOOM_INCREMENT = 25;
private static final String LOOK_NORTH = "Look North";
private static final String LOOK_SOUTH = "Look South";
private static final String LOOK_EAST = "Look East";
private static final String LOOK_WEST = "Look West";
private boolean controlDown;
// flags used to store the mousedown states
@@ -96,6 +103,60 @@ public class CameraPlugin extends Plugin implements KeyListener, MouseListener
return configManager.getConfig(CameraConfig.class);
}
@Override
protected void startUp()
{
rightClick = false;
middleClick = false;
menuHasEntries = false;
client.setCameraPitchRelaxerEnabled(cameraConfig.relaxCameraPitch());
keyManager.registerKeyListener(this);
mouseManager.registerMouseListener(this);
}
@Override
protected void shutDown()
{
client.setCameraPitchRelaxerEnabled(false);
keyManager.unregisterKeyListener(this);
mouseManager.unregisterMouseListener(this);
controlDown = false;
}
@Subscribe
public void onMenuEntryAdded(MenuEntryAdded menuEntryAdded)
{
if (menuEntryAdded.getOpcode() == MenuOpcode.WIDGET_DEFAULT.getId() && menuEntryAdded.getOption().equals(LOOK_NORTH) && cameraConfig.compassLook())
{
MenuEntry[] menuEntries = client.getMenuEntries();
int len = menuEntries.length;
MenuEntry north = menuEntries[len - 1];
menuEntries = Arrays.copyOf(menuEntries, len + 3);
// The handling for these entries is done in ToplevelCompassOp.rs2asm
menuEntries[--len] = createCameraLookEntry(menuEntryAdded, 4, LOOK_WEST);
menuEntries[++len] = createCameraLookEntry(menuEntryAdded, 3, LOOK_EAST);
menuEntries[++len] = createCameraLookEntry(menuEntryAdded, 2, LOOK_SOUTH);
menuEntries[++len] = north;
client.setMenuEntries(menuEntries);
}
}
private MenuEntry createCameraLookEntry(MenuEntryAdded lookNorth, int identifier, String option)
{
MenuEntry m = new MenuEntry();
m.setOption(option);
m.setTarget(lookNorth.getTarget());
m.setIdentifier(identifier);
m.setOpcode(MenuOpcode.WIDGET_DEFAULT.getId());
m.setParam0(lookNorth.getParam0());
m.setParam1(lookNorth.getParam1());
return m;
}
@Subscribe
private void onScriptCallbackEvent(ScriptCallbackEvent event)
{
@@ -169,27 +230,6 @@ public class CameraPlugin extends Plugin implements KeyListener, MouseListener
}
}
@Override
protected void startUp()
{
rightClick = false;
middleClick = false;
menuHasEntries = false;
client.setCameraPitchRelaxerEnabled(cameraConfig.relaxCameraPitch());
keyManager.registerKeyListener(this);
mouseManager.registerMouseListener(this);
}
@Override
protected void shutDown()
{
client.setCameraPitchRelaxerEnabled(false);
keyManager.unregisterKeyListener(this);
mouseManager.unregisterMouseListener(this);
controlDown = false;
}
@Subscribe
private void onConfigChanged(ConfigChanged ev)
{

View File

@@ -29,7 +29,9 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import net.runelite.api.Client;
import net.runelite.api.ScriptID;
import net.runelite.api.VarClientInt;
import net.runelite.api.VarClientStr;
import net.runelite.api.vars.InputType;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.input.KeyListener;
@@ -56,7 +58,11 @@ class ChatKeyboardListener implements KeyListener
{
if (chatCommandsConfig.clearSingleWord().matches(e))
{
String input = client.getVar(VarClientStr.CHATBOX_TYPED_TEXT);
int inputTye = client.getVar(VarClientInt.INPUT_TYPE);
String input = inputTye == InputType.NONE.getType()
? client.getVar(VarClientStr.CHATBOX_TYPED_TEXT)
: client.getVar(VarClientStr.INPUT_TEXT);
if (input != null)
{
// remove trailing space
@@ -77,20 +83,27 @@ class ChatKeyboardListener implements KeyListener
replacement = "";
}
clientThread.invoke(() ->
{
client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, replacement);
client.runScript(ScriptID.CHAT_PROMPT_INIT);
});
clientThread.invoke(() -> applyText(inputTye, replacement));
}
}
else if (chatCommandsConfig.clearChatBox().matches(e))
{
clientThread.invoke(() ->
{
client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, "");
client.runScript(ScriptID.CHAT_PROMPT_INIT);
});
int inputTye = client.getVar(VarClientInt.INPUT_TYPE);
clientThread.invoke(() -> applyText(inputTye, ""));
}
}
private void applyText(int inputType, String replacement)
{
if (inputType == InputType.NONE.getType())
{
client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, replacement);
client.runScript(ScriptID.CHAT_PROMPT_INIT);
}
else if (inputType == InputType.PRIVATE_MESSAGE.getType())
{
client.setVar(VarClientStr.INPUT_TEXT, replacement);
client.runScript(ScriptID.CHAT_TEXT_INPUT_REBUILD, "");
}
}

View File

@@ -173,7 +173,7 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu
new EmoteClue("Yawn in Draynor Marketplace. Equip studded leather chaps, an iron kiteshield and a steel longsword.", "Draynor", DRAYNOR_VILLAGE_MARKET, new WorldPoint(3083, 3253, 0), YAWN, item(STUDDED_CHAPS), item(IRON_KITESHIELD), item(STEEL_LONGSWORD)),
new EmoteClue("Yawn in the Castle Wars lobby. Shrug before you talk to me. Equip a ruby amulet, a mithril scimitar and a Wilderness cape.", "Castle Wars", CASTLE_WARS_BANK, new WorldPoint(2440, 3092, 0), YAWN, SHRUG, item(RUBY_AMULET), item(MITHRIL_SCIMITAR), range("Any team cape", TEAM1_CAPE, TEAM50_CAPE)),
new EmoteClue("Yawn in the rogues' general store. Beware of double agents! Equip an adamant square shield, blue dragon vambraces and a rune pickaxe.", "Rogues general store", NOTERAZZOS_SHOP_IN_THE_WILDERNESS, new WorldPoint(3026, 3701, 0), YAWN, item(ADAMANT_SQ_SHIELD), item(BLUE_DHIDE_VAMB), item(RUNE_PICKAXE)),
new EmoteClue("Yawn at the top of Trollheim. Equip a lava battlestaff, black dragonhide vambraces and a mind shield.", "Trollheim Mountain", ON_TOP_OF_TROLLHEIM_MOUNTAIN, new WorldPoint(2887, 3676, 0), YAWN, item(LAVA_BATTLESTAFF), item(BLACK_DHIDE_VAMB), item(MIND_SHIELD)),
new EmoteClue("Yawn at the top of Trollheim. Equip a lava battlestaff, black dragonhide vambraces and a mind shield.", "Trollheim Mountain", ON_TOP_OF_TROLLHEIM_MOUNTAIN, new WorldPoint(2887, 3676, 0), YAWN, any("Lava battlestaff", item(LAVA_BATTLESTAFF), item(LAVA_BATTLESTAFF_21198)), item(BLACK_DHIDE_VAMB), item(MIND_SHIELD)),
new EmoteClue("Yawn in the centre of Arceuus library. Nod your head before you talk to me. Equip blue dragonhide vambraces, adamant boots and an adamant dagger.", "Arceuus library", ENTRANCE_OF_THE_ARCEUUS_LIBRARY, new WorldPoint(1632, 3807, 0), YAWN, YES, item(BLUE_DHIDE_VAMB), item(ADAMANT_BOOTS), item(ADAMANT_DAGGER)),
new EmoteClue("Swing a bullroarer at the top of the watchtower. Beware of double agents! Equip a dragon plateskirt, climbing boots and a dragon chainbody.", "Yanille watchtower", TOP_FLOOR_OF_THE_YANILLE_WATCHTOWER, new WorldPoint(2932, 4712, 0), BULL_ROARER, item(DRAGON_PLATESKIRT), item(CLIMBING_BOOTS), item(DRAGON_CHAINBODY_3140), item(ItemID.BULL_ROARER)),
new EmoteClue("Blow a raspberry at Gypsy Aris in her tent. Equip a gold ring and a gold necklace.", "Varrock", GYPSY_TENT_ENTRANCE, new WorldPoint(3203, 3424, 0), RASPBERRY, item(GOLD_RING), item(GOLD_NECKLACE)),

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2017, 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.plugins.config;
import java.awt.Dimension;
import javax.swing.JPanel;
import net.runelite.client.ui.PluginPanel;
class FixedWidthPanel extends JPanel
{
@Override
public Dimension getPreferredSize()
{
return new Dimension(PluginPanel.PANEL_WIDTH, super.getPreferredSize().height);
}
}

View File

@@ -112,9 +112,9 @@ public class PluginListItem extends JPanel
CONFIG_ICON = new ImageIcon(configIcon);
ON_SWITCHER = new ImageIcon(ImageUtil.recolorImage(onSwitcher, ColorScheme.BRAND_BLUE));
ON_STAR = new ImageIcon(ImageUtil.recolorImage(onStar, ColorScheme.BRAND_BLUE));
CONFIG_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(configIcon, -100));
CONFIG_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(configIcon, -100));
BufferedImage offSwitcherImage = ImageUtil.flipImage(
ImageUtil.grayscaleOffset(
ImageUtil.luminanceScale(
ImageUtil.grayscaleImage(onSwitcher),
0.61f
),
@@ -122,7 +122,7 @@ public class PluginListItem extends JPanel
false
);
OFF_SWITCHER = new ImageIcon(offSwitcherImage);
BufferedImage offStar = ImageUtil.grayscaleOffset(
BufferedImage offStar = ImageUtil.luminanceScale(
ImageUtil.grayscaleImage(onStar),
0.77f
);

View File

@@ -37,6 +37,7 @@ import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.ItemDefinition;
import net.runelite.api.ItemID;
import net.runelite.api.events.ChatMessage;
@@ -335,8 +336,8 @@ public class ExaminePlugin extends Plugin
// quantity is at least 1
quantity = Math.max(1, quantity);
int itemCompositionPrice = itemComposition.getPrice();
final int gePrice = itemManager.getItemPrice(id);
final int alchPrice = itemCompositionPrice <= 0 ? 0 : itemManager.getAlchValue(itemComposition);
final long gePrice = itemManager.getItemPrice(id);
final long alchPrice = itemCompositionPrice <= 0 ? 0 : Math.round(itemCompositionPrice * Constants.HIGH_ALCHEMY_MULTIPLIER);
if (gePrice > 0 || alchPrice > 0)
{

View File

@@ -1,6 +1,7 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
* Copyright (c) 2019, Bram91 <https://github.com/bram91>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,6 +26,7 @@
*/
package net.runelite.client.plugins.hiscore;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import java.awt.Dimension;
@@ -37,9 +39,10 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import javax.annotation.Nullable;
import javax.inject.Inject;
@@ -66,7 +69,9 @@ import net.runelite.http.api.hiscore.HiscoreEndpoint;
import net.runelite.http.api.hiscore.HiscoreResult;
import net.runelite.http.api.hiscore.HiscoreSkill;
import static net.runelite.http.api.hiscore.HiscoreSkill.*;
import net.runelite.http.api.hiscore.HiscoreSkillType;
import net.runelite.http.api.hiscore.Skill;
import org.apache.commons.lang3.StringUtils;
@Slf4j
@Singleton
@@ -89,6 +94,27 @@ public class HiscorePanel extends PluginPanel
CONSTRUCTION, HUNTER
);
/**
* Bosses, ordered in the way they should be displayed in the panel.
*/
private static final List<HiscoreSkill> BOSSES = ImmutableList.of(
ABYSSAL_SIRE, ALCHEMICAL_HYDRA, BARROWS_CHESTS,
BRYOPHYTA, CALLISTO, CERBERUS,
CHAMBERS_OF_XERIC, CHAMBERS_OF_XERIC_CHALLENGE_MODE, CHAOS_ELEMENTAL,
CHAOS_FANATIC, COMMANDER_ZILYANA, CORPOREAL_BEAST,
DAGANNOTH_PRIME, DAGANNOTH_REX, DAGANNOTH_SUPREME,
CRAZY_ARCHAEOLOGIST, DERANGED_ARCHAEOLOGIST, GENERAL_GRAARDOR,
GIANT_MOLE, GROTESQUE_GUARDIANS, HESPORI,
KALPHITE_QUEEN, KING_BLACK_DRAGON, KRAKEN,
KREEARRA, KRIL_TSUTSAROTH, MIMIC,
OBOR, SARACHNIS, SCORPIA,
SKOTIZO, THE_GAUNTLET, THE_CORRUPTED_GAUNTLET,
THEATRE_OF_BLOOD, THERMONUCLEAR_SMOKE_DEVIL, TZKAL_ZUK,
TZTOK_JAD, VENENATIS, VETION,
VORKATH, WINTERTODT, ZALCANO,
ZULRAH
);
@Inject
ScheduledExecutorService executor;
@@ -100,7 +126,8 @@ public class HiscorePanel extends PluginPanel
private final IconTextField searchBar;
private final List<JLabel> skillLabels = new ArrayList<>();
// Not an enummap because we need null keys for combat
private final Map<HiscoreSkill, JLabel> skillLabels = new HashMap<>();
/* Container of all the selectable endpoints (ironman, deadman, etc) */
private final MaterialTabGroup tabGroup;
@@ -215,16 +242,15 @@ public class HiscorePanel extends PluginPanel
c.gridy++;
// Panel that holds skill icons
GridLayout stats = new GridLayout(8, 3);
JPanel statsPanel = new JPanel();
statsPanel.setLayout(stats);
statsPanel.setLayout(new GridLayout(8, 3));
statsPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
statsPanel.setBorder(new EmptyBorder(5, 0, 5, 0));
// For each skill on the ingame skill panel, create a Label and add it to the UI
for (HiscoreSkill skill : SKILLS)
{
JPanel panel = makeSkillPanel(skill);
JPanel panel = makeHiscorePanel(skill);
statsPanel.add(panel);
}
@@ -232,11 +258,11 @@ public class HiscorePanel extends PluginPanel
c.gridy++;
JPanel totalPanel = new JPanel();
totalPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
totalPanel.setLayout(new GridLayout(1, 2));
totalPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
totalPanel.add(makeSkillPanel(null)); //combat has no hiscore skill, refered to as null
totalPanel.add(makeSkillPanel(OVERALL));
totalPanel.add(makeHiscorePanel(null)); //combat has no hiscore skill, referred to as null
totalPanel.add(makeHiscorePanel(OVERALL));
add(totalPanel, c);
c.gridy++;
@@ -247,14 +273,28 @@ public class HiscorePanel extends PluginPanel
minigamePanel.setLayout(new GridLayout(2, 3));
minigamePanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
minigamePanel.add(makeSkillPanel(CLUE_SCROLL_ALL));
minigamePanel.add(makeSkillPanel(LEAGUE_POINTS));
minigamePanel.add(makeSkillPanel(LAST_MAN_STANDING));
minigamePanel.add(makeSkillPanel(BOUNTY_HUNTER_ROGUE));
minigamePanel.add(makeSkillPanel(BOUNTY_HUNTER_HUNTER));
minigamePanel.add(makeHiscorePanel(CLUE_SCROLL_ALL));
minigamePanel.add(makeHiscorePanel(LEAGUE_POINTS));
minigamePanel.add(makeHiscorePanel(LAST_MAN_STANDING));
minigamePanel.add(makeHiscorePanel(BOUNTY_HUNTER_ROGUE));
minigamePanel.add(makeHiscorePanel(BOUNTY_HUNTER_HUNTER));
add(minigamePanel, c);
c.gridy++;
JPanel bossPanel = new JPanel();
bossPanel.setLayout(new GridLayout(0, 3));
bossPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
// For each boss on the hi-scores, create a Label and add it to the UI
for (HiscoreSkill skill : BOSSES)
{
JPanel panel = makeHiscorePanel(skill);
bossPanel.add(panel);
}
add(bossPanel, c);
c.gridy++;
}
@Override
@@ -265,24 +305,29 @@ public class HiscorePanel extends PluginPanel
}
/* Builds a JPanel displaying an icon and level/number associated with it */
private JPanel makeSkillPanel(HiscoreSkill skill)
private JPanel makeHiscorePanel(HiscoreSkill skill)
{
HiscoreSkillType skillType = skill == null ? HiscoreSkillType.SKILL : skill.getType();
JLabel label = new JLabel();
label.setFont(FontManager.getRunescapeSmallFont());
label.setText("--");
label.setText(pad("--", skillType));
String skillName = (skill == null ? "combat" : skill.getName().toLowerCase());
String directory = "/skill_icons";
if (skillName.equals("combat") || skillName.equals("overall"))
String directory;
if (skill == null || skill == OVERALL)
{
// Cannot use SpriteManager as HiscorePlugin loads before a Client is available
directory += "/";
directory = "/skill_icons/";
}
else if (skill.getType() == HiscoreSkillType.BOSS)
{
directory = "bosses/";
}
else
{
directory += "_small/";
directory = "/skill_icons_small/";
}
String skillName = (skill == null ? "combat" : skill.name().toLowerCase());
String skillIcon = directory + skillName + ".png";
log.debug("Loading skill icon from {}", skillIcon);
@@ -294,8 +339,8 @@ public class HiscorePanel extends PluginPanel
JPanel skillPanel = new JPanel();
skillPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
skillPanel.setBorder(new EmptyBorder(2, 0, 2, 0));
skillLabels.add(label);
skillPanel.add(skillLabels.get(skillLabels.size() - 1));
skillLabels.put(skill, label);
skillPanel.add(label);
return skillPanel;
}
@@ -330,9 +375,13 @@ public class HiscorePanel extends PluginPanel
searchBar.setIcon(IconTextField.Icon.LOADING_DARKER);
loading = true;
for (JLabel label : skillLabels)
for (Map.Entry<HiscoreSkill, JLabel> entry : skillLabels.entrySet())
{
label.setText("--");
HiscoreSkill skill = entry.getKey();
JLabel label = entry.getValue();
HiscoreSkillType skillType = skill == null ? HiscoreSkillType.SKILL : skill.getType();
label.setText(pad("--", skillType));
label.setToolTipText(null);
}
@@ -370,10 +419,10 @@ public class HiscorePanel extends PluginPanel
searchBar.setEditable(true);
loading = false;
int index = 0;
for (JLabel label : skillLabels)
for (Map.Entry<HiscoreSkill, JLabel> entry : skillLabels.entrySet())
{
HiscoreSkill skill = find(index);
HiscoreSkill skill = entry.getKey();
JLabel label = entry.getValue();
Skill s;
if (skill == null)
@@ -395,7 +444,7 @@ public class HiscorePanel extends PluginPanel
else if ((s = result.getSkill(skill)) != null)
{
final long exp = s.getExperience();
final boolean isSkill = SKILLS.contains(skill);
final boolean isSkill = skill.getType() == HiscoreSkillType.SKILL;
int level = -1;
if (plugin.isVirtualLevels() && isSkill && exp > -1L)
{
@@ -410,12 +459,11 @@ public class HiscorePanel extends PluginPanel
if (level != -1)
{
label.setText(Integer.toString(level));
label.setText(pad(formatLevel(level), skill.getType()));
}
}
label.setToolTipText(detailsHtml(result, skill));
index++;
}
}
@@ -429,37 +477,6 @@ public class HiscorePanel extends PluginPanel
this.searchBar.removeKeyListener(l);
}
/*
Returns a hiscore skill based on it's display order.
*/
private HiscoreSkill find(int index)
{
if (index < SKILLS.size())
{
return SKILLS.get(index);
}
switch (index - SKILLS.size())
{
case 0:
return null;
case 1:
return OVERALL;
case 2:
return CLUE_SCROLL_ALL;
case 3:
return LEAGUE_POINTS;
case 4:
return LAST_MAN_STANDING;
case 5:
return BOUNTY_HUNTER_ROGUE;
case 6:
return BOUNTY_HUNTER_HUNTER;
}
return null;
}
/*
Builds a html string to display on tooltip (when hovering a skill).
*/
@@ -556,36 +573,50 @@ public class HiscorePanel extends PluginPanel
}
default:
{
Skill requestedSkill = result.getSkill(skill);
final long experience = requestedSkill.getExperience();
String rank = (requestedSkill.getRank() == -1) ? "Unranked" : QuantityFormatter.formatNumber(requestedSkill.getRank());
String exp = (experience == -1L) ? "Unranked" : QuantityFormatter.formatNumber(experience);
String remainingXp;
if (experience == -1L)
if (skill.getType() == HiscoreSkillType.BOSS)
{
remainingXp = "Unranked";
Skill requestedSkill = result.getSkill(skill);
String rank = "Unranked";
String lvl = "0";
if (requestedSkill != null)
{
rank = (requestedSkill.getRank() == -1) ? "Unranked" : QuantityFormatter.formatNumber(requestedSkill.getRank());
lvl = (requestedSkill.getLevel() == -1 ? "0" : QuantityFormatter.formatNumber(requestedSkill.getLevel()));
}
content += "<p><span style = 'color:white'>Boss:</span> " + skill.getName() + "</p>";
content += "<p><span style = 'color:white'>Rank:</span> " + rank + "</p>";
content += "<p><span style = 'color:white'>KC:</span> " + lvl + "</p>";
}
else
{
int currentLevel = Experience.getLevelForXp((int) experience);
remainingXp = (currentLevel + 1 <= Experience.MAX_VIRT_LEVEL) ? QuantityFormatter.formatNumber(Experience.getXpForLevel(currentLevel + 1) - experience) : "0";
Skill requestedSkill = result.getSkill(skill);
final long experience = requestedSkill.getExperience();
String rank = (requestedSkill.getRank() == -1) ? "Unranked" : QuantityFormatter.formatNumber(requestedSkill.getRank());
String exp = (experience == -1L) ? "Unranked" : QuantityFormatter.formatNumber(experience);
String remainingXp;
if (experience == -1L)
{
remainingXp = "Unranked";
}
else
{
int currentLevel = Experience.getLevelForXp((int) experience);
remainingXp = (currentLevel + 1 <= Experience.MAX_VIRT_LEVEL) ? QuantityFormatter.formatNumber(Experience.getXpForLevel(currentLevel + 1) - experience) : "0";
}
content += "<p><span style = 'color:white'>Skill:</span> " + skill.getName() + "</p>";
content += "<p><span style = 'color:white'>Rank:</span> " + rank + "</p>";
content += "<p><span style = 'color:white'>Experience:</span> " + exp + "</p>";
content += "<p><span style = 'color:white'>Remaining XP:</span> " + remainingXp + "</p>";
}
content += "<p><span style = 'color:white'>Skill:</span> " + skill.getName() + "</p>";
content += "<p><span style = 'color:white'>Rank:</span> " + rank + "</p>";
content += "<p><span style = 'color:white'>Experience:</span> " + exp + "</p>";
content += "<p><span style = 'color:white'>Remaining XP:</span> " + remainingXp + "</p>";
break;
}
}
}
/**
* Adds a html progress bar to the hover information
*/
if (SKILLS.contains(skill))
// Add a html progress bar to the hover information
if (skill != null && skill.getType() == HiscoreSkillType.SKILL)
{
long experience = 0;
if (skill != null)
@@ -644,4 +675,24 @@ public class HiscorePanel extends PluginPanel
}
return HiscoreEndpoint.NORMAL;
}
@VisibleForTesting
static String formatLevel(int level)
{
if (level < 10000)
{
return Integer.toString(level);
}
else
{
return (level / 1000) + "k";
}
}
private static String pad(String str, HiscoreSkillType type)
{
// Left pad label text to keep labels aligned
int pad = type == HiscoreSkillType.BOSS ? 4 : 2;
return StringUtils.leftPad(str, pad);
}
}

View File

@@ -70,7 +70,7 @@ public class HiscorePlugin extends Plugin
{
private static final String LOOKUP = "Lookup";
private static final String KICK_OPTION = "Kick";
private static final ImmutableList<String> AFTER_OPTIONS = ImmutableList.of("Message", "Add ignore", "Remove friend", KICK_OPTION);
private static final ImmutableList<String> AFTER_OPTIONS = ImmutableList.of("Message", "Add ignore", "Remove friend", "Delete", KICK_OPTION);
private static final Pattern BOUNTY_PATTERN = Pattern.compile("<col=ff0000>You've been assigned a target: (.*)</col>");
// config
@@ -194,10 +194,11 @@ public class HiscorePlugin extends Plugin
String option = event.getOption();
if (groupId == WidgetInfo.FRIENDS_LIST.getGroupId() || groupId == WidgetInfo.CLAN_CHAT.getGroupId() ||
groupId == WidgetInfo.CHATBOX.getGroupId() && !KICK_OPTION.equals(option) || //prevent from adding for Kick option (interferes with the raiding party one)
groupId == WidgetInfo.RAIDING_PARTY.getGroupId() || groupId == WidgetInfo.PRIVATE_CHAT_MESSAGE.getGroupId())
groupId == WidgetInfo.CHATBOX.getGroupId() && !KICK_OPTION.equals(option) || //prevent from adding for Kick option (interferes with the raiding party one)
groupId == WidgetInfo.RAIDING_PARTY.getGroupId() || groupId == WidgetInfo.PRIVATE_CHAT_MESSAGE.getGroupId() ||
groupId == WidgetInfo.IGNORE_LIST.getGroupId())
{
if (!AFTER_OPTIONS.contains(option))
if (!AFTER_OPTIONS.contains(option) || (option.equals("Delete") && groupId != WidgetInfo.IGNORE_LIST.getGroupId()))
{
return;
}

View File

@@ -120,7 +120,77 @@ enum ItemIdentification
RED_TOPAZ(Type.GEM, "Topaz", "T", ItemID.UNCUT_RED_TOPAZ, ItemID.RED_TOPAZ),
DRAGONSTONE(Type.GEM, "Dragon", "DR", ItemID.UNCUT_DRAGONSTONE, ItemID.DRAGONSTONE),
ONYX(Type.GEM, "Onyx", "ON", ItemID.UNCUT_ONYX, ItemID.ONYX),
ZENYTE(Type.GEM, "Zenyte", "Z", ItemID.UNCUT_ZENYTE, ItemID.ZENYTE);
ZENYTE(Type.GEM, "Zenyte", "Z", ItemID.UNCUT_ZENYTE, ItemID.ZENYTE),
// Potions
ATTACK(Type.POTION, "Att", "A", ItemID.ATTACK_POTION4, ItemID.ATTACK_POTION3, ItemID.ATTACK_POTION2, ItemID.ATTACK_POTION1),
STRENGTH(Type.POTION, "Str", "S", ItemID.STRENGTH_POTION4, ItemID.STRENGTH_POTION3, ItemID.STRENGTH_POTION2, ItemID.STRENGTH_POTION1),
DEFENCE(Type.POTION, "Def", "D", ItemID.DEFENCE_POTION4, ItemID.DEFENCE_POTION3, ItemID.DEFENCE_POTION2, ItemID.DEFENCE_POTION1),
COMBAT(Type.POTION, "Com", "D", ItemID.COMBAT_POTION4, ItemID.COMBAT_POTION3, ItemID.COMBAT_POTION2, ItemID.COMBAT_POTION1),
MAGIC(Type.POTION, "Magic", "M", ItemID.MAGIC_POTION4, ItemID.MAGIC_POTION3, ItemID.MAGIC_POTION2, ItemID.MAGIC_POTION1),
RANGING(Type.POTION, "Range", "R", ItemID.RANGING_POTION4, ItemID.RANGING_POTION3, ItemID.RANGING_POTION2, ItemID.RANGING_POTION1),
BASTION(Type.POTION, "Bastion", "B", ItemID.BASTION_POTION4, ItemID.BASTION_POTION3, ItemID.BASTION_POTION2, ItemID.BASTION_POTION1),
BATTLEMAGE(Type.POTION, "BatMage", "B.M", ItemID.BATTLEMAGE_POTION4, ItemID.BATTLEMAGE_POTION3, ItemID.BATTLEMAGE_POTION2, ItemID.BATTLEMAGE_POTION1),
SUPER_ATTACK(Type.POTION, "S.Att", "S.A", ItemID.SUPER_ATTACK4, ItemID.SUPER_ATTACK3, ItemID.SUPER_ATTACK2, ItemID.SUPER_ATTACK1),
SUPER_STRENGTH(Type.POTION, "S.Str", "S.S", ItemID.SUPER_STRENGTH4, ItemID.SUPER_STRENGTH3, ItemID.SUPER_STRENGTH2, ItemID.SUPER_STRENGTH1),
SUPER_DEFENCE(Type.POTION, "S.Def", "S.D", ItemID.SUPER_DEFENCE4, ItemID.SUPER_DEFENCE3, ItemID.SUPER_DEFENCE2, ItemID.SUPER_DEFENCE1),
SUPER_COMBAT(Type.POTION, "S.Com", "S.C", ItemID.SUPER_COMBAT_POTION4, ItemID.SUPER_COMBAT_POTION3, ItemID.SUPER_COMBAT_POTION2, ItemID.SUPER_COMBAT_POTION1),
SUPER_RANGING(Type.POTION, "S.Range", "S.Ra", ItemID.SUPER_RANGING_4, ItemID.SUPER_RANGING_3, ItemID.SUPER_RANGING_2, ItemID.SUPER_RANGING_1),
SUPER_MAGIC(Type.POTION, "S.Magic", "S.M", ItemID.SUPER_MAGIC_POTION_4, ItemID.SUPER_MAGIC_POTION_3, ItemID.SUPER_MAGIC_POTION_2, ItemID.SUPER_MAGIC_POTION_1),
DIVINE_SUPER_ATTACK(Type.POTION, "S.Att", "S.A", ItemID.DIVINE_SUPER_ATTACK_POTION4, ItemID.DIVINE_SUPER_ATTACK_POTION3, ItemID.DIVINE_SUPER_ATTACK_POTION2, ItemID.DIVINE_SUPER_ATTACK_POTION1),
DIVINE_SUPER_DEFENCE(Type.POTION, "S.Def", "S.D", ItemID.DIVINE_SUPER_DEFENCE_POTION4, ItemID.DIVINE_SUPER_DEFENCE_POTION3, ItemID.DIVINE_SUPER_DEFENCE_POTION2, ItemID.DIVINE_SUPER_DEFENCE_POTION1),
DIVINE_SUPER_STRENGTH(Type.POTION, "S.Str", "S.S", ItemID.DIVINE_SUPER_STRENGTH_POTION4, ItemID.DIVINE_SUPER_STRENGTH_POTION3, ItemID.DIVINE_SUPER_STRENGTH_POTION2, ItemID.DIVINE_SUPER_STRENGTH_POTION1),
DIVINE_SUPER_COMBAT(Type.POTION, "S.Com", "S.C", ItemID.DIVINE_SUPER_COMBAT_POTION4, ItemID.DIVINE_SUPER_COMBAT_POTION3, ItemID.DIVINE_SUPER_COMBAT_POTION2, ItemID.DIVINE_SUPER_COMBAT_POTION1),
DIVINE_RANGING(Type.POTION, "Range", "R", ItemID.DIVINE_RANGING_POTION4, ItemID.DIVINE_RANGING_POTION3, ItemID.DIVINE_RANGING_POTION2, ItemID.DIVINE_RANGING_POTION1),
DIVINE_MAGIC(Type.POTION, "Magic", "M", ItemID.DIVINE_MAGIC_POTION4, ItemID.DIVINE_MAGIC_POTION3, ItemID.DIVINE_MAGIC_POTION2, ItemID.DIVINE_MAGIC_POTION1),
RESTORE(Type.POTION, "Restore", "Re", ItemID.RESTORE_POTION4, ItemID.RESTORE_POTION3, ItemID.RESTORE_POTION2, ItemID.RESTORE_POTION1),
SUPER_RESTORE(Type.POTION, "S.Rest", "S.Re", ItemID.SUPER_RESTORE4, ItemID.SUPER_RESTORE3, ItemID.SUPER_RESTORE2, ItemID.SUPER_RESTORE1),
PRAYER(Type.POTION, "Prayer", "P", ItemID.PRAYER_POTION4, ItemID.PRAYER_POTION3, ItemID.PRAYER_POTION2, ItemID.PRAYER_POTION1),
ENERGY(Type.POTION, "Energy", "En", ItemID.ENERGY_POTION4, ItemID.ENERGY_POTION3, ItemID.ENERGY_POTION2, ItemID.ENERGY_POTION1),
SUPER_ENERGY(Type.POTION, "S.Energ", "S.En", ItemID.SUPER_ENERGY4, ItemID.SUPER_ENERGY3, ItemID.SUPER_ENERGY2, ItemID.SUPER_ENERGY1),
STAMINA(Type.POTION, "Stamina", "St", ItemID.STAMINA_POTION4, ItemID.STAMINA_POTION3, ItemID.STAMINA_POTION2, ItemID.STAMINA_POTION1),
OVERLOAD(Type.POTION, "Overloa", "OL", ItemID.OVERLOAD_4, ItemID.OVERLOAD_3, ItemID.OVERLOAD_2, ItemID.OVERLOAD_1),
ABSORPTION(Type.POTION, "Absorb", "Ab", ItemID.ABSORPTION_4, ItemID.ABSORPTION_3, ItemID.ABSORPTION_2, ItemID.ABSORPTION_1),
ZAMORAK_BREW(Type.POTION, "ZammyBr", "Za", ItemID.ZAMORAK_BREW4, ItemID.ZAMORAK_BREW3, ItemID.ZAMORAK_BREW2, ItemID.ZAMORAK_BREW1),
SARADOMIN_BREW(Type.POTION, "SaraBr", "Sa", ItemID.SARADOMIN_BREW4, ItemID.SARADOMIN_BREW3, ItemID.SARADOMIN_BREW2, ItemID.SARADOMIN_BREW1),
ANTIPOISON(Type.POTION, "AntiP", "AP", ItemID.ANTIPOISON4, ItemID.ANTIPOISON3, ItemID.ANTIPOISON2, ItemID.ANTIPOISON1),
SUPERANTIPOISON(Type.POTION, "S.AntiP", "S.AP", ItemID.SUPERANTIPOISON4, ItemID.SUPERANTIPOISON3, ItemID.SUPERANTIPOISON2, ItemID.SUPERANTIPOISON1),
ANTIDOTE_P(Type.POTION, "Antid+", "A+", ItemID.ANTIDOTE4, ItemID.ANTIDOTE3, ItemID.ANTIDOTE2, ItemID.ANTIDOTE1),
ANTIDOTE_PP(Type.POTION, "Antid++", "A++", ItemID.ANTIDOTE4_5952, ItemID.ANTIDOTE3_5954, ItemID.ANTIDOTE2_5956, ItemID.ANTIDOTE1_5958),
ANTIVENOM(Type.POTION, "Anti-V", "AV", ItemID.ANTIVENOM4, ItemID.ANTIVENOM3, ItemID.ANTIVENOM2, ItemID.ANTIVENOM1),
ANTIVENOM_P(Type.POTION, "Anti-V+", "AV+", ItemID.ANTIVENOM4_12913, ItemID.ANTIVENOM3_12915, ItemID.ANTIVENOM2_12917, ItemID.ANTIVENOM1_12919),
RELICYMS_BALM(Type.POTION, "Relicym", "R.B", ItemID.RELICYMS_BALM4, ItemID.RELICYMS_BALM3, ItemID.RELICYMS_BALM2, ItemID.RELICYMS_BALM1),
SANFEW_SERUM(Type.POTION, "Sanfew", "Sf", ItemID.SANFEW_SERUM4, ItemID.SANFEW_SERUM3, ItemID.SANFEW_SERUM2, ItemID.SANFEW_SERUM1),
ANTIFIRE(Type.POTION, "Antif", "Af", ItemID.ANTIFIRE_POTION4, ItemID.ANTIFIRE_POTION3, ItemID.ANTIFIRE_POTION2, ItemID.ANTIFIRE_POTION1),
EXTENDED_ANTIFIRE(Type.POTION, "E.Antif", "E.Af", ItemID.EXTENDED_ANTIFIRE4, ItemID.EXTENDED_ANTIFIRE3, ItemID.EXTENDED_ANTIFIRE2, ItemID.EXTENDED_ANTIFIRE1),
SUPER_ANTIFIRE(Type.POTION, "S.Antif", "S.Af", ItemID.SUPER_ANTIFIRE_POTION4, ItemID.SUPER_ANTIFIRE_POTION3, ItemID.SUPER_ANTIFIRE_POTION2, ItemID.SUPER_ANTIFIRE_POTION1),
EXTENDED_SUPER_ANTIFIRE(Type.POTION, "ES.Antif", "ES.Af", ItemID.EXTENDED_SUPER_ANTIFIRE4, ItemID.EXTENDED_SUPER_ANTIFIRE3, ItemID.EXTENDED_SUPER_ANTIFIRE2, ItemID.EXTENDED_SUPER_ANTIFIRE1),
SERUM_207(Type.POTION, "Ser207", "S7", ItemID.SERUM_207_4, ItemID.SERUM_207_3, ItemID.SERUM_207_2, ItemID.SERUM_207_1),
SERUM_208(Type.POTION, "Ser208", "S8", ItemID.SERUM_208_4, ItemID.SERUM_208_3, ItemID.SERUM_208_2, ItemID.SERUM_208_1),
COMPOST(Type.POTION, "Compost", "Cp", ItemID.COMPOST_POTION4, ItemID.COMPOST_POTION3, ItemID.COMPOST_POTION2, ItemID.COMPOST_POTION1),
// Unfinished Potions
GUAM_POTION(Type.POTION, "Guam", "G", ItemID.GUAM_POTION_UNF),
MARRENTILL_POTION(Type.POTION, "Marren", "M", ItemID.MARRENTILL_POTION_UNF),
TARROMIN_POTION(Type.POTION, "Tarro", "TAR", ItemID.TARROMIN_POTION_UNF),
HARRALANDER_POTION(Type.POTION, "Harra", "H", ItemID.HARRALANDER_POTION_UNF),
RANARR_POTION(Type.POTION, "Ranarr", "R", ItemID.RANARR_POTION_UNF),
TOADFLAX_POTION(Type.POTION, "Toad", "TOA", ItemID.TOADFLAX_POTION_UNF),
IRIT_POTION(Type.POTION, "Irit", "I", ItemID.IRIT_POTION_UNF),
AVANTOE_POTION(Type.POTION, "Avan", "A", ItemID.AVANTOE_POTION_UNF),
KWUARM_POTION(Type.POTION, "Kwuarm", "K", ItemID.KWUARM_POTION_UNF),
SNAPDRAGON_POTION(Type.POTION, "Snap", "S", ItemID.SNAPDRAGON_POTION_UNF),
CADANTINE_POTION(Type.POTION, "Cadan", "C", ItemID.CADANTINE_POTION_UNF),
LANTADYME_POTION(Type.POTION, "Lanta", "L", ItemID.LANTADYME_POTION_UNF),
DWARF_WEED_POTION(Type.POTION, "Dwarf", "D", ItemID.DWARF_WEED_POTION_UNF),
TORSTOL_POTION(Type.POTION, "Torstol", "TOR", ItemID.TORSTOL_POTION_UNF);
final Type type;
final String medName;
@@ -163,6 +233,7 @@ enum ItemIdentification
HERB,
SAPLING,
ORE,
GEM
GEM,
POTION
}
}

View File

@@ -103,4 +103,14 @@ public interface ItemIdentificationConfig extends Config
{
return false;
}
@ConfigItem(
keyName = "showPotions",
name = "Potions",
description = "Show identification on Potions"
)
default boolean showPotions()
{
return false;
}
}

View File

@@ -98,6 +98,12 @@ class ItemIdentificationOverlay extends WidgetItemOverlay
return;
}
break;
case POTION:
if (!plugin.isShowPotions())
{
return;
}
break;
}
graphics.setFont(FontManager.getRunescapeSmallFont());

View File

@@ -68,6 +68,8 @@ public class ItemIdentificationPlugin extends Plugin
private boolean showOres;
@Getter(AccessLevel.PACKAGE)
private boolean showGems;
@Getter(AccessLevel.PACKAGE)
private boolean showPotions;
@Provides
ItemIdentificationConfig getConfig(ConfigManager configManager)
@@ -108,5 +110,6 @@ public class ItemIdentificationPlugin extends Plugin
this.showSaplings = config.showSaplings();
this.showOres = config.showOres();
this.showGems = config.showGems();
this.showPotions = config.showPotions();
}
}

View File

@@ -236,7 +236,7 @@ class ItemPricesOverlay extends Overlay
if (gePrice > 0)
{
itemStringBuilder.append("EX: ")
.append(QuantityFormatter.quantityToStackSize(gePrice * qty))
.append(QuantityFormatter.quantityToStackSize((long) gePrice * qty))
.append(" gp");
if (plugin.isShowEA() && qty > 1)
{
@@ -253,7 +253,7 @@ class ItemPricesOverlay extends Overlay
}
itemStringBuilder.append("HA: ")
.append(QuantityFormatter.quantityToStackSize(haValue * qty))
.append(QuantityFormatter.quantityToStackSize((long) haValue * qty))
.append(" gp");
if (plugin.isShowEA() && qty > 1)
{
@@ -269,7 +269,7 @@ class ItemPricesOverlay extends Overlay
itemStringBuilder.append("</br>");
itemStringBuilder.append("HA Profit: ")
.append(ColorUtil.wrapWithColorTag(String.valueOf(haProfit * qty), haColor))
.append(ColorUtil.wrapWithColorTag(String.valueOf((long) haProfit * qty), haColor))
.append(" gp");
if (plugin.isShowEA() && qty > 1)
{

View File

@@ -191,7 +191,7 @@ class ItemStatChanges
add(combo(2, boost(HITPOINTS, 5), heal(RUN_ENERGY, 5)), GUTHIX_REST1, GUTHIX_REST2, GUTHIX_REST3, GUTHIX_REST4);
// Misc/run energy
add(heal(RUN_ENERGY, 10), WHITE_TREE_FRUIT);
add(combo(food(3), range(heal(RUN_ENERGY, 5), heal(RUN_ENERGY, 10))), WHITE_TREE_FRUIT);
add(heal(RUN_ENERGY, 30), STRANGE_FRUIT);
add(heal(RUN_ENERGY, 50), MINT_CAKE);
add(combo(food(12), heal(RUN_ENERGY, 50)), GOUT_TUBER);

View File

@@ -29,8 +29,6 @@ import com.google.inject.Inject;
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Comparator;
import java.util.HashMap;
@@ -51,7 +49,7 @@ import net.runelite.client.util.ImageUtil;
class KourendLibraryPanel extends PluginPanel
{
private static final ImageIcon RESET_ICON;
private static final ImageIcon RESET_CLICK_ICON;
private static final ImageIcon RESET_HOVER_ICON;
private final KourendLibraryConfig config;
private final Library library;
@@ -62,7 +60,7 @@ class KourendLibraryPanel extends PluginPanel
{
final BufferedImage resetIcon = ImageUtil.getResourceStreamFromClass(KourendLibraryPanel.class, "/util/reset.png");
RESET_ICON = new ImageIcon(resetIcon);
RESET_CLICK_ICON = new ImageIcon(ImageUtil.alphaOffset(resetIcon, -100));
RESET_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(resetIcon, -100));
}
@Inject
@@ -99,21 +97,11 @@ class KourendLibraryPanel extends PluginPanel
});
JButton reset = new JButton("Reset", RESET_ICON);
reset.addMouseListener(new MouseAdapter()
reset.setRolloverIcon(RESET_HOVER_ICON);
reset.addActionListener(ev ->
{
@Override
public void mousePressed(MouseEvent mouseEvent)
{
reset.setIcon(RESET_CLICK_ICON);
library.reset();
update();
}
@Override
public void mouseReleased(MouseEvent mouseEvent)
{
reset.setIcon(RESET_ICON);
}
library.reset();
update();
});
add(reset, BorderLayout.NORTH);

View File

@@ -40,6 +40,7 @@ import lombok.extern.slf4j.Slf4j;
import net.runelite.api.AnimationID;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemContainer;
@@ -50,6 +51,7 @@ import net.runelite.api.Player;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.AnimationChanged;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.ItemContainerChanged;
import net.runelite.api.events.MenuOptionClicked;
@@ -175,6 +177,7 @@ public class KourendLibraryPlugin extends Plugin
lastBookcaseClick = null;
lastBookcaseAnimatedOn = null;
playerBooks = null;
npcsToMark.clear();
}
@Subscribe
@@ -187,34 +190,31 @@ public class KourendLibraryPlugin extends Plugin
if (ev.getKey().equals("hideVarlamoreEnvoy"))
{
panel.reload();
SwingUtilities.invokeLater(panel::reload);
}
this.hideButton = config.hideButton();
this.hideDuplicateBook = config.hideDuplicateBook();
this.hideVarlamoreEnvoy = config.hideVarlamoreEnvoy();
this.showTutorialOverlay = config.showTutorialOverlay();
SwingUtilities.invokeLater(() ->
else if (ev.getKey().equals("hideButton"))
{
if (!this.hideButton)
SwingUtilities.invokeLater(() ->
{
clientToolbar.addNavigation(navButton);
}
else
{
Player lp = client.getLocalPlayer();
boolean inRegion = lp != null && lp.getWorldLocation().getRegionID() == REGION;
if (inRegion)
if (!config.hideButton())
{
clientToolbar.addNavigation(navButton);
}
else
{
clientToolbar.removeNavigation(navButton);
Player lp = client.getLocalPlayer();
boolean inRegion = lp != null && lp.getWorldLocation().getRegionID() == REGION;
if (inRegion)
{
clientToolbar.addNavigation(navButton);
}
else
{
clientToolbar.removeNavigation(navButton);
}
}
}
});
});
}
}
@Subscribe
@@ -250,7 +250,17 @@ public class KourendLibraryPlugin extends Plugin
}
@Subscribe
private void onGameTick(GameTick tick)
public void onGameStateChanged(GameStateChanged event)
{
if (event.getGameState() == GameState.LOGIN_SCREEN ||
event.getGameState() == GameState.HOPPING)
{
npcsToMark.clear();
}
}
@Subscribe
public void onGameTick(GameTick tick)
{
boolean inRegion = client.getLocalPlayer().getWorldLocation().getRegionID() == REGION;
if (this.hideButton && inRegion != buttonAttached)

View File

@@ -130,21 +130,26 @@ class Library
}
else if (state != SolvedState.NO_DATA)
{
// We know all of the possible things in this shelf.
if (book != null || bookcase.getPossibleBooks().stream().noneMatch(Book::isDarkManuscript))
// Reset if the book we found isn't what we expected
if (book != null && !bookcase.getPossibleBooks().contains(book))
{
// Check to see if our guess is wrong
if (!bookcase.getPossibleBooks().contains(book))
{
reset();
}
reset();
}
}
// Everything is known, nothing to do
if (state == SolvedState.COMPLETE)
{
return;
// Reset if we found nothing when we expected something that wasn't a Dark Manuscript, since the layout has changed
if (book == null && !bookcase.getPossibleBooks().isEmpty() && bookcase.getPossibleBooks().stream().noneMatch(Book::isDarkManuscript))
{
reset();
}
else
{
// Everything is known, nothing to do
return;
}
}
log.debug("Setting bookcase {} to {}", bookcase.getIndex(), book);

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2019, Rami <https://github.com/Rami-J>
* 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.menuentryswapper;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public enum GEItemCollectMode
{
DEFAULT("Default"),
ITEMS("Collect-items"),
NOTES("Collect-notes"),
BANK("Bank");
private final String name;
@Override
public String toString()
{
return name;
}
}

View File

@@ -1,210 +0,0 @@
/*
* Copyright (c) 2019, Shaun Dreclin <https://github.com/ShaunDreclin>
* 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.musicindicator;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Singleton;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.EnumDefinition;
import net.runelite.api.EnumID;
import net.runelite.api.VarPlayer;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.VarbitChanged;
import net.runelite.client.chat.ChatColorType;
import net.runelite.client.chat.ChatMessageBuilder;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.chat.QueuedMessage;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType;
@PluginDescriptor(
name = "Music Track Indicator",
description = "Show chat notifications when unlocking music tracks",
type = PluginType.UTILITY,
enabledByDefault = false
)
@Singleton
public class MusicIndicatorPlugin extends Plugin
{
private static final List<VarPlayer> MUSIC_TRACK_VARPS = ImmutableList.of(
VarPlayer.MUSIC_TRACKS_UNLOCKED_1, VarPlayer.MUSIC_TRACKS_UNLOCKED_2, VarPlayer.MUSIC_TRACKS_UNLOCKED_3,
VarPlayer.MUSIC_TRACKS_UNLOCKED_4, VarPlayer.MUSIC_TRACKS_UNLOCKED_5, VarPlayer.MUSIC_TRACKS_UNLOCKED_6,
VarPlayer.MUSIC_TRACKS_UNLOCKED_7, VarPlayer.MUSIC_TRACKS_UNLOCKED_8, VarPlayer.MUSIC_TRACKS_UNLOCKED_9,
VarPlayer.MUSIC_TRACKS_UNLOCKED_10, VarPlayer.MUSIC_TRACKS_UNLOCKED_11, VarPlayer.MUSIC_TRACKS_UNLOCKED_12,
VarPlayer.MUSIC_TRACKS_UNLOCKED_13, VarPlayer.MUSIC_TRACKS_UNLOCKED_14, VarPlayer.MUSIC_TRACKS_UNLOCKED_15,
VarPlayer.MUSIC_TRACKS_UNLOCKED_16, VarPlayer.MUSIC_TRACKS_UNLOCKED_17, VarPlayer.MUSIC_TRACKS_UNLOCKED_18,
VarPlayer.MUSIC_TRACKS_UNLOCKED_19
);
private static final Map<Integer, VarPlayer> VARP_INDEX_TO_VARPLAYER = MUSIC_TRACK_VARPS.stream()
.collect(Collectors.collectingAndThen(Collectors.toMap(VarPlayer::getId, Function.identity()),
ImmutableMap::copyOf));
@Inject
private Client client;
@Inject
private ChatMessageManager chatMessageManager;
// Mapping of relevant varps to their values, used to compare against new values
private final Map<VarPlayer, Integer> musicTrackVarpValues = new HashMap<>();
private boolean loggingIn;
@Override
public void startUp()
{
loggingIn = true;
}
@Override
public void shutDown()
{
musicTrackVarpValues.clear();
}
@Subscribe
private void onGameStateChanged(GameStateChanged event)
{
switch (event.getGameState())
{
case LOGGING_IN:
case CONNECTION_LOST:
case HOPPING:
musicTrackVarpValues.clear();
loggingIn = true;
}
}
@Subscribe
private void onGameTick(GameTick event)
{
if (!loggingIn)
{
return;
}
loggingIn = false;
for (VarPlayer musicTrackVarp : MUSIC_TRACK_VARPS)
{
int value = client.getVar(musicTrackVarp);
musicTrackVarpValues.put(musicTrackVarp, value);
}
}
@Subscribe
private void onVarbitChanged(VarbitChanged event)
{
int idx = event.getIndex();
VarPlayer varPlayer = VARP_INDEX_TO_VARPLAYER.get(idx);
if (varPlayer == null)
{
return;
}
// Old varplayer values have not been initialized yet
if (musicTrackVarpValues.isEmpty())
{
return;
}
assert musicTrackVarpValues.containsKey(varPlayer);
int newValue = client.getVar(varPlayer);
int oldValue = musicTrackVarpValues.put(varPlayer, newValue);
int musicTracksUnlocked = ~oldValue & newValue;
if (musicTracksUnlocked == 0)
{
return;
}
final EnumDefinition names = client.getEnum(EnumID.MUSIC_TRACK_NAMES);
final int varpId = MUSIC_TRACK_VARPS.indexOf(varPlayer) + 1;
for (int bit = 0; bit < Integer.SIZE; ++bit)
{
if ((musicTracksUnlocked & (1 << bit)) == 0)
{
continue;
}
int musicTrackId = getTrackId(varpId, bit);
String musicTrackName = names.getStringValue(musicTrackId);
sendChatMessage("You have unlocked a new music track: " + musicTrackName + ".");
}
}
/**
* Get the id for a track identified by the given varp and a bit index
*
* @param variableId
* @param bit
* @return
*/
private int getTrackId(int variableId, int bit)
{
// values are packed into a coordgrid
int packed = (variableId << 14) | bit;
EnumDefinition ids = client.getEnum(EnumID.MUSIC_TRACK_IDS);
for (int key : ids.getKeys())
{
int value = ids.getIntValue(key);
if (value == packed)
{
return key;
}
}
return -1;
}
private void sendChatMessage(String chatMessage)
{
final String message = new ChatMessageBuilder()
.append(ChatColorType.HIGHLIGHT)
.append(chatMessage)
.build();
chatMessageManager.queue(
QueuedMessage.builder()
.type(ChatMessageType.CONSOLE)
.runeLiteFormattedMessage(message)
.build());
}
}

View File

@@ -351,7 +351,7 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
{
if (worldPoint.getRegionX() == objectPoint.getRegionX()
&& worldPoint.getRegionY() == objectPoint.getRegionY()
&& object.getPlane() == objectPoint.getZ())
&& worldPoint.getPlane() == objectPoint.getZ())
{
// Transform object to get the name which matches against what we've stored
ObjectDefinition objectDefinition = getObjectDefinition(object.getId());
@@ -453,7 +453,7 @@ public class ObjectIndicatorsPlugin extends Plugin implements KeyListener
regionId,
worldPoint.getRegionX(),
worldPoint.getRegionY(),
client.getPlane());
worldPoint.getPlane());
Set<ObjectPoint> objectPoints = points.computeIfAbsent(regionId, k -> new HashSet<>());

View File

@@ -117,7 +117,7 @@ public class PestControlNpc
NpcID.PORTAL_1748, // Novice Blue Active
NpcID.PORTAL_1749, // Novice Yellow Active
NpcID.PORTAL_1750, // Novice Red Active
NpcID.PORTAL_1739, // Intermediate Purple Active
NpcID.PORTAL, // Intermediate Purple Active
NpcID.PORTAL_1740, // Intermediate Blue Active
NpcID.PORTAL_1741, // Intermediate Yellow Active
NpcID.PORTAL_1742 // Intermediate Red Active

View File

@@ -108,7 +108,7 @@ class ScreenMarkerPanel extends JPanel
static
{
final BufferedImage borderImg = ImageUtil.getResourceStreamFromClass(ScreenMarkerPlugin.class, "border_color_icon.png");
final BufferedImage borderImgHover = ImageUtil.grayscaleOffset(borderImg, -150);
final BufferedImage borderImgHover = ImageUtil.luminanceOffset(borderImg, -150);
BORDER_COLOR_ICON = new ImageIcon(borderImg);
BORDER_COLOR_HOVER_ICON = new ImageIcon(borderImgHover);
@@ -116,7 +116,7 @@ class ScreenMarkerPanel extends JPanel
NO_BORDER_COLOR_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(borderImgHover, -100));
final BufferedImage fillImg = ImageUtil.getResourceStreamFromClass(ScreenMarkerPlugin.class, "fill_color_icon.png");
final BufferedImage fillImgHover = ImageUtil.grayscaleOffset(fillImg, -150);
final BufferedImage fillImgHover = ImageUtil.luminanceOffset(fillImg, -150);
FILL_COLOR_ICON = new ImageIcon(fillImg);
FILL_COLOR_HOVER_ICON = new ImageIcon(fillImgHover);
@@ -124,7 +124,7 @@ class ScreenMarkerPanel extends JPanel
NO_FILL_COLOR_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(fillImgHover, -100));
final BufferedImage opacityImg = ImageUtil.getResourceStreamFromClass(ScreenMarkerPlugin.class, "opacity_icon.png");
final BufferedImage opacityImgHover = ImageUtil.grayscaleOffset(opacityImg, -150);
final BufferedImage opacityImgHover = ImageUtil.luminanceOffset(opacityImg, -150);
FULL_OPACITY_ICON = new ImageIcon(opacityImg);
FULL_OPACITY_HOVER_ICON = new ImageIcon(opacityImgHover);

View File

@@ -218,12 +218,14 @@ enum Task
STEEL_DRAGONS("Steel dragons", ItemID.STEEL_DRAGON),
SULPHUR_LIZARDS("Sulphur Lizards", ItemID.SULPHUR_LIZARD),
SUQAHS("Suqahs", ItemID.SUQAH_TOOTH),
TEMPLE_SPIDERS("Temple Spiders", ItemID.RED_SPIDERS_EGGS),
TERROR_DOGS("Terror dogs", ItemID.TERROR_DOG),
THERMONUCLEAR_SMOKE_DEVIL("Thermonuclear Smoke Devil", ItemID.PET_SMOKE_DEVIL),
TROLLS("Trolls", ItemID.TROLL_GUARD),
TUROTH("Turoth", ItemID.TUROTH),
TZHAAR("Tzhaar", ItemID.ENSOULED_TZHAAR_HEAD,
Collections.singletonList("Tz-"), Collections.emptyList(), false),
UNDEAD_DRUIDS("Undead Druids", ItemID.MASK_OF_RANUL),
VAMPIRES("Vampires", ItemID.STAKE,
asList("Vampyre", "Vyrewatch", "Vampire"), Collections.emptyList()),
VENENATIS("Venenatis", ItemID.VENENATIS_SPIDERLING),
@@ -257,6 +259,7 @@ enum Task
"Death Plateau",
"Evil Chicken's Lair",
"Fossil Island",
"Forthos Dungeon",
"Fremennik Slayer Dungeon",
"God Wars Dungeon",
"Iorwerth Dungeon",

View File

@@ -30,12 +30,12 @@ import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.time.Duration;
import java.time.format.DateTimeParseException;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
@@ -44,7 +44,7 @@ import lombok.AccessLevel;
import lombok.Getter;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.components.FlatTextField;
import net.runelite.client.ui.components.IconButton;
import net.runelite.client.util.SwingUtil;
abstract class ClockPanel extends JPanel
{
@@ -64,7 +64,7 @@ abstract class ClockPanel extends JPanel
final JPanel rightActions;
private final FlatTextField nameInput;
private final IconButton startPauseButton;
private final JToggleButton startPauseButton;
private final FlatTextField displayInput;
@Getter(AccessLevel.PACKAGE)
@@ -168,28 +168,17 @@ abstract class ClockPanel extends JPanel
leftActions = new JPanel(new FlowLayout(FlowLayout.LEFT, 6, 0));
leftActions.setBackground(ColorScheme.DARKER_GRAY_COLOR);
startPauseButton = new IconButton(ClockTabPanel.START_ICON);
startPauseButton = new JToggleButton(ClockTabPanel.START_ICON);
startPauseButton.setRolloverIcon(ClockTabPanel.START_ICON_HOVER);
startPauseButton.setSelectedIcon(ClockTabPanel.PAUSE_ICON);
startPauseButton.setRolloverSelectedIcon(ClockTabPanel.PAUSE_ICON_HOVER);
SwingUtil.removeButtonDecorations(startPauseButton);
startPauseButton.setPreferredSize(new Dimension(16, 14));
updateActivityStatus();
startPauseButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseEntered(MouseEvent e)
{
startPauseButton.setIcon(clock.isActive() ? ClockTabPanel.PAUSE_ICON_HOVER : ClockTabPanel.START_ICON_HOVER);
}
@Override
public void mouseExited(MouseEvent e)
{
startPauseButton.setIcon(clock.isActive() ? ClockTabPanel.PAUSE_ICON : ClockTabPanel.START_ICON);
}
});
startPauseButton.addActionListener(e ->
{
if (clock.isActive())
if (!startPauseButton.isSelected())
{
clock.pause();
}
@@ -202,7 +191,9 @@ abstract class ClockPanel extends JPanel
clockManager.saveToConfig();
});
IconButton resetButton = new IconButton(ClockTabPanel.RESET_ICON, ClockTabPanel.RESET_ICON_HOVER);
JButton resetButton = new JButton(ClockTabPanel.RESET_ICON);
resetButton.setRolloverIcon(ClockTabPanel.RESET_ICON_HOVER);
SwingUtil.removeButtonDecorations(resetButton);
resetButton.setPreferredSize(new Dimension(16, 14));
resetButton.setToolTipText("Reset " + clockType);
@@ -250,7 +241,7 @@ abstract class ClockPanel extends JPanel
displayInput.setEditable(editable && !isActive);
displayInput.getTextField().setForeground(isActive ? ACTIVE_CLOCK_COLOR : INACTIVE_CLOCK_COLOR);
startPauseButton.setToolTipText(isActive ? "Pause " + clockType : "Start " + clockType);
startPauseButton.setIcon(isActive ? ClockTabPanel.PAUSE_ICON : ClockTabPanel.START_ICON);
startPauseButton.setSelected(isActive);
if (editable && clock.getDisplayTime() == 0 && !isActive)
{

View File

@@ -32,6 +32,7 @@ import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
@@ -40,9 +41,9 @@ import net.runelite.client.plugins.timetracking.TimeTrackingPlugin;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.DynamicGridLayout;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.components.IconButton;
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.SwingUtil;
public class ClockTabPanel extends TabContentPanel
{
@@ -74,15 +75,15 @@ public class ClockTabPanel extends TabContentPanel
BufferedImage addIcon = ImageUtil.getResourceStreamFromClass(TimeTrackingPlugin.class, "add_icon.png");
DELETE_ICON = new ImageIcon(deleteIcon);
DELETE_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(deleteIcon, -80));
DELETE_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(deleteIcon, -80));
LAP_ICON = new ImageIcon(lapIcon);
LAP_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(lapIcon, -80));
LAP_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(lapIcon, -80));
PAUSE_ICON = new ImageIcon(pauseIcon);
PAUSE_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(pauseIcon, -80));
PAUSE_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(pauseIcon, -80));
RESET_ICON = new ImageIcon(resetIcon);
RESET_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(resetIcon, -80));
RESET_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(resetIcon, -80));
START_ICON = new ImageIcon(startIcon);
START_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(startIcon, -80));
START_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(startIcon, -80));
ADD_ICON = new ImageIcon(addIcon);
ADD_ICON_HOVER = new ImageIcon(ImageUtil.alphaOffset(addIcon, 0.53f));
}
@@ -150,7 +151,9 @@ public class ClockTabPanel extends TabContentPanel
headerLabel.setFont(FontManager.getRunescapeSmallFont());
panel.add(headerLabel, BorderLayout.CENTER);
IconButton addButton = new IconButton(ADD_ICON, ADD_ICON_HOVER);
JButton addButton = new JButton(ADD_ICON);
addButton.setRolloverIcon(ADD_ICON_HOVER);
SwingUtil.removeButtonDecorations(addButton);
addButton.setPreferredSize(new Dimension(14, 14));
addButton.setToolTipText("Add a " + type);
addButton.addActionListener(actionListener);

View File

@@ -30,13 +30,14 @@ import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.components.IconButton;
import net.runelite.client.util.SwingUtil;
class StopwatchPanel extends ClockPanel
{
@@ -57,7 +58,9 @@ class StopwatchPanel extends ClockPanel
contentContainer.add(lapsContainer);
IconButton lapButton = new IconButton(ClockTabPanel.LAP_ICON, ClockTabPanel.LAP_ICON_HOVER);
JButton lapButton = new JButton(ClockTabPanel.LAP_ICON);
lapButton.setRolloverIcon(ClockTabPanel.LAP_ICON_HOVER);
SwingUtil.removeButtonDecorations(lapButton);
lapButton.setPreferredSize(new Dimension(16, 14));
lapButton.setToolTipText("Add lap time");
@@ -70,7 +73,9 @@ class StopwatchPanel extends ClockPanel
leftActions.add(lapButton);
IconButton deleteButton = new IconButton(ClockTabPanel.DELETE_ICON, ClockTabPanel.DELETE_ICON_HOVER);
JButton deleteButton = new JButton(ClockTabPanel.DELETE_ICON);
deleteButton.setRolloverIcon(ClockTabPanel.DELETE_ICON_HOVER);
SwingUtil.removeButtonDecorations(deleteButton);
deleteButton.setPreferredSize(new Dimension(16, 14));
deleteButton.setToolTipText("Delete stopwatch");
deleteButton.addActionListener(e -> clockManager.removeStopwatch(stopwatch));

View File

@@ -25,7 +25,8 @@
package net.runelite.client.plugins.timetracking.clocks;
import java.awt.Dimension;
import net.runelite.client.ui.components.IconButton;
import javax.swing.JButton;
import net.runelite.client.util.SwingUtil;
class TimerPanel extends ClockPanel
{
@@ -33,7 +34,9 @@ class TimerPanel extends ClockPanel
{
super(clockManager, timer, "timer", true);
IconButton deleteButton = new IconButton(ClockTabPanel.DELETE_ICON, ClockTabPanel.DELETE_ICON_HOVER);
JButton deleteButton = new JButton(ClockTabPanel.DELETE_ICON);
SwingUtil.removeButtonDecorations(deleteButton);
deleteButton.setRolloverIcon(ClockTabPanel.DELETE_ICON_HOVER);
deleteButton.setPreferredSize(new Dimension(16, 14));
deleteButton.setToolTipText("Delete timer");
deleteButton.addActionListener(e -> clockManager.removeTimer(timer));

View File

@@ -29,10 +29,30 @@ import java.time.Duration;
import java.util.Map;
import javax.annotation.Nullable;
import lombok.Getter;
import static net.runelite.api.NullObjectID.NULL_10823;
import static net.runelite.api.NullObjectID.NULL_10835;
import net.runelite.api.ObjectID;
import static net.runelite.api.ObjectID.*;
import static net.runelite.api.ObjectID.MAGIC_TREE_10834;
import static net.runelite.api.NullObjectID.NULL_10835;
import static net.runelite.api.ObjectID.MAHOGANY;
import static net.runelite.api.ObjectID.MAHOGANY_36688;
import static net.runelite.api.ObjectID.MAPLE_TREE_10832;
import static net.runelite.api.ObjectID.MAPLE_TREE_36681;
import static net.runelite.api.ObjectID.OAK_10820;
import static net.runelite.api.ObjectID.OAK_TREE_4540;
import static net.runelite.api.ObjectID.REDWOOD_29670;
import static net.runelite.api.ObjectID.TEAK;
import static net.runelite.api.ObjectID.TEAK_36686;
import static net.runelite.api.ObjectID.TREE;
import static net.runelite.api.ObjectID.TREE_1277;
import static net.runelite.api.ObjectID.TREE_1278;
import static net.runelite.api.ObjectID.TREE_1279;
import static net.runelite.api.ObjectID.TREE_1280;
import static net.runelite.api.ObjectID.WILLOW;
import static net.runelite.api.ObjectID.WILLOW_10829;
import static net.runelite.api.ObjectID.WILLOW_10831;
import static net.runelite.api.ObjectID.WILLOW_10833;
import static net.runelite.api.ObjectID.YEW;
import static net.runelite.api.NullObjectID.NULL_10823;
import static net.runelite.api.ObjectID.YEW_36683;
@Getter
enum Tree
@@ -40,13 +60,31 @@ enum Tree
REGULAR_TREE(null, TREE, TREE_1277, TREE_1278, TREE_1279, TREE_1280),
OAK_TREE(Duration.ofMillis(8500), ObjectID.OAK_TREE, OAK_TREE_4540, OAK_10820),
WILLOW_TREE(Duration.ofMillis(8500), WILLOW, WILLOW_10829, WILLOW_10831, WILLOW_10833),
MAPLE_TREE(Duration.ofSeconds(35), ObjectID.MAPLE_TREE, MAPLE_TREE_10832, MAPLE_TREE_36681),
MAPLE_TREE(Duration.ofSeconds(35), ObjectID.MAPLE_TREE, MAPLE_TREE_10832, MAPLE_TREE_36681)
{
@Override
Duration getRespawnTime(int region)
{
return region == MISCELLANIA_REGION ? Duration.ofMillis(8500) : super.respawnTime;
}
},
TEAK_TREE(Duration.ofMillis(8500), TEAK, TEAK_36686),
MAHOGANY_TREE(Duration.ofMillis(8500), MAHOGANY, MAHOGANY_36688),
YEW_TREE(Duration.ofMinutes(1), YEW, NULL_10823, YEW_36683),
MAGIC_TREE(Duration.ofMinutes(2), MAGIC_TREE_10834, NULL_10835),
REDWOOD(Duration.ofMinutes(2), ObjectID.REDWOOD, REDWOOD_29670);
@Nullable
private final Duration respawnTime;
private final int[] treeIds;
Tree(Duration respawnTime, int... treeIds)
{
this.respawnTime = respawnTime;
this.treeIds = treeIds;
}
private static final int MISCELLANIA_REGION = 10044;
private static final Map<Integer, Tree> TREES;
static
@@ -64,14 +102,9 @@ enum Tree
TREES = builder.build();
}
@Nullable
private final Duration respawnTime;
private final int[] treeIds;
Tree(@org.jetbrains.annotations.Nullable Duration respawnTime, int... treeIds)
Duration getRespawnTime(int region)
{
this.respawnTime = respawnTime;
this.treeIds = treeIds;
return respawnTime;
}
static Tree findTree(int objectId)

View File

@@ -112,6 +112,7 @@ public class WoodcuttingPlugin extends Plugin
private int treeTypeID;
@Getter(AccessLevel.PACKAGE)
private int gpEarned;
private int currentPlane;
@Provides
WoodcuttingConfig getConfig(ConfigManager configManager)
@@ -153,6 +154,7 @@ public class WoodcuttingPlugin extends Plugin
private void onGameTick(GameTick gameTick)
{
recentlyLoggedIn = false;
currentPlane = client.getPlane();
respawns.removeIf(TreeRespawn::isExpired);
@@ -217,14 +219,16 @@ public class WoodcuttingPlugin extends Plugin
Tree tree = Tree.findTree(object.getId());
if (tree != null)
{
if (tree.getRespawnTime() != null && !recentlyLoggedIn)
if (tree.getRespawnTime() != null && !recentlyLoggedIn && currentPlane == object.getPlane())
{
Point max = object.getSceneMaxLocation();
Point min = object.getSceneMinLocation();
int lenX = max.getX() - min.getX();
int lenY = max.getY() - min.getY();
log.debug("Adding respawn timer for {} tree at {}", tree, object.getLocalLocation());
TreeRespawn treeRespawn = new TreeRespawn(tree, lenX, lenY, WorldPoint.fromScene(client, min.getX(), min.getY(), client.getPlane()), Instant.now(), (int) tree.getRespawnTime().toMillis());
final int region = client.getLocalPlayer().getWorldLocation().getRegionID();
TreeRespawn treeRespawn = new TreeRespawn(tree, lenX, lenY, WorldPoint.fromScene(client, min.getX(), min.getY(), client.getPlane()), Instant.now(), (int) tree.getRespawnTime(region).toMillis());
respawns.add(treeRespawn);
}

View File

@@ -58,7 +58,7 @@ class WorldTableHeader extends JPanel
{
final BufferedImage arrowDown = ImageUtil.getResourceStreamFromClass(WorldHopperPlugin.class, "arrow_down.png");
final BufferedImage arrowUp = ImageUtil.rotateImage(arrowDown, Math.PI);
final BufferedImage arrowUpFaded = ImageUtil.grayscaleOffset(arrowUp, -80);
final BufferedImage arrowUpFaded = ImageUtil.luminanceOffset(arrowUp, -80);
ARROW_UP = new ImageIcon(arrowUpFaded);
final BufferedImage highlightArrowDown = ImageUtil.fillImage(arrowDown, HIGHLIGHT_COLOR);

View File

@@ -686,7 +686,19 @@ public class XpTrackerPlugin extends Plugin
xpPauseState.tickXp(skill, skillExperience, this.pauseSkillAfter);
}
xpPauseState.tickLogout(this.pauseOnLogout, !GameState.LOGIN_SCREEN.equals(client.getGameState()));
final boolean loggedIn;
switch (client.getGameState())
{
case LOGIN_SCREEN:
case LOGGING_IN:
case LOGIN_SCREEN_AUTHENTICATOR:
loggedIn = false;
break;
default:
loggedIn = true;
break;
}
xpPauseState.tickLogout(this.pauseOnLogout, loggedIn);
if (lastTickMillis == 0)
{

View File

@@ -100,8 +100,11 @@ public class DynamicGridLayout extends GridLayout
// scaling factors
final Dimension pd = preferredLayoutSize(parent);
final double sw = (1.0 * parent.getWidth()) / pd.width;
final double sh = (1.0 * parent.getHeight()) / pd.height;
final Insets parentInsets = parent.getInsets();
int wborder = parentInsets.left + parentInsets.right;
int hborder = parentInsets.top + parentInsets.bottom;
final double sw = (1.0 * parent.getWidth() - wborder) / (pd.width - wborder);
final double sh = (1.0 * parent.getHeight() - hborder) / (pd.height - hborder);
final int[] w = new int[ncols];
final int[] h = new int[nrows];

View File

@@ -36,9 +36,9 @@ import lombok.Getter;
public abstract class PluginPanel extends JPanel
{
public static final int PANEL_WIDTH = 225;
private static final int SCROLLBAR_WIDTH = 17;
private static final int OFFSET = 6;
private static final EmptyBorder BORDER_PADDING = new EmptyBorder(OFFSET, OFFSET, OFFSET, OFFSET);
public static final int SCROLLBAR_WIDTH = 17;
public static final int BORDER_OFFSET = 6;
private static final EmptyBorder BORDER_PADDING = new EmptyBorder(BORDER_OFFSET, BORDER_OFFSET, BORDER_OFFSET, BORDER_OFFSET);
private static final Dimension OUTER_PREFERRED_SIZE = new Dimension(PluginPanel.PANEL_WIDTH + SCROLLBAR_WIDTH, 0);
@Getter(AccessLevel.PROTECTED)

View File

@@ -36,13 +36,12 @@ import java.awt.image.PixelGrabber;
import java.awt.image.RescaleOp;
import java.awt.image.WritableRaster;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import javax.imageio.ImageIO;
import javax.swing.GrayFilter;
import java.util.function.Predicate;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.IndexedSprite;
@@ -63,7 +62,7 @@ public class ImageUtil
* Creates a {@link BufferedImage} from an {@link Image}.
*
* @param image An Image to be converted to a BufferedImage.
* @return A BufferedImage instance of the same given image.
* @return A BufferedImage instance of the same given image.
*/
public static BufferedImage bufferedImageFromImage(final Image image)
{
@@ -72,23 +71,37 @@ public class ImageUtil
return (BufferedImage) image;
}
final BufferedImage out = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
final Graphics2D g2d = out.createGraphics();
return toARGB(image);
}
/**
* Creates an ARGB {@link BufferedImage} from an {@link Image}.
*/
public static BufferedImage toARGB(final Image image)
{
if (image instanceof BufferedImage && ((BufferedImage) image).getType() == BufferedImage.TYPE_INT_ARGB)
{
return (BufferedImage) image;
}
BufferedImage out = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = out.createGraphics();
g2d.drawImage(image, 0, 0, null);
g2d.dispose();
return out;
}
/**
* Offsets an image in the grayscale (darkens/brightens) by a given offset.
* Offsets an image's luminance by a given value.
*
* @param image The image to be darkened or brightened.
* @param rawImg The image to be darkened or brightened.
* @param offset A signed 8-bit integer value to brighten or darken the image with.
* Values above 0 will brighten, and values below 0 will darken.
* @return The given image with its brightness adjusted by the given offset.
* @return The given image with its brightness adjusted by the given offset.
*/
public static BufferedImage grayscaleOffset(final BufferedImage image, final int offset)
public static BufferedImage luminanceOffset(final Image rawImg, final int offset)
{
BufferedImage image = toARGB(rawImg);
final float offsetFloat = (float) offset;
final int numComponents = image.getColorModel().getNumComponents();
final float[] scales = new float[numComponents];
@@ -106,15 +119,16 @@ public class ImageUtil
}
/**
* Offsets an image in the grayscale (darkens/brightens) by a given percentage.
* Changes an images luminance by a scaling factor
*
* @param image The image to be darkened or brightened.
* @param rawImg The image to be darkened or brightened.
* @param percentage The ratio to darken or brighten the given image.
* Values above 1 will brighten, and values below 1 will darken.
* @return The given image with its brightness scaled by the given percentage.
* @return The given image with its brightness scaled by the given percentage.
*/
public static BufferedImage grayscaleOffset(final BufferedImage image, final float percentage)
public static BufferedImage luminanceScale(final Image rawImg, final float percentage)
{
BufferedImage image = toARGB(rawImg);
final int numComponents = image.getColorModel().getNumComponents();
final float[] scales = new float[numComponents];
final float[] offsets = new float[numComponents];
@@ -133,14 +147,15 @@ public class ImageUtil
/**
* Offsets an image's alpha component by a given offset.
*
* @param image The image to be made more or less transparent.
* @param rawImg The image to be made more or less transparent.
* @param offset A signed 8-bit integer value to modify the image's alpha component with.
* Values above 0 will increase transparency, and values below 0 will decrease
* transparency.
* @return The given image with its alpha component adjusted by the given offset.
* @return The given image with its alpha component adjusted by the given offset.
*/
public static BufferedImage alphaOffset(final BufferedImage image, final int offset)
public static BufferedImage alphaOffset(final Image rawImg, final int offset)
{
BufferedImage image = toARGB(rawImg);
final float offsetFloat = (float) offset;
final int numComponents = image.getColorModel().getNumComponents();
final float[] scales = new float[numComponents];
@@ -155,14 +170,15 @@ public class ImageUtil
/**
* Offsets an image's alpha component by a given percentage.
*
* @param image The image to be made more or less transparent.
* @param rawImg The image to be made more or less transparent.
* @param percentage The ratio to modify the image's alpha component with.
* Values above 1 will increase transparency, and values below 1 will decrease
* transparency.
* @return The given image with its alpha component scaled by the given percentage.
* @return The given image with its alpha component scaled by the given percentage.
*/
public static BufferedImage alphaOffset(final BufferedImage image, final float percentage)
public static BufferedImage alphaOffset(final Image rawImg, final float percentage)
{
BufferedImage image = toARGB(rawImg);
final int numComponents = image.getColorModel().getNumComponents();
final float[] scales = new float[numComponents];
final float[] offsets = new float[numComponents];
@@ -177,7 +193,7 @@ public class ImageUtil
* Creates a grayscale image from the given image.
*
* @param image The source image to be converted.
* @return A copy of the given imnage, with colors converted to grayscale.
* @return A copy of the given imnage, with colors converted to grayscale.
*/
public static BufferedImage grayscaleImage(final BufferedImage image)
{
@@ -188,8 +204,8 @@ public class ImageUtil
/**
* Re-size a BufferedImage to the given dimensions.
*
* @param image the BufferedImage.
* @param newWidth The width to set the BufferedImage to.
* @param image the BufferedImage.
* @param newWidth The width to set the BufferedImage to.
* @param newHeight The height to set the BufferedImage to.
* @return The BufferedImage with the specified dimensions
*/
@@ -205,7 +221,7 @@ public class ImageUtil
* @param image The image whose canvas should be re-sized.
* @param newWidth The width to set the BufferedImage to.
* @param newHeight The height to set the BufferedImage to.
* @return The BufferedImage centered within canvas of given dimensions.
* @return The BufferedImage centered within canvas of given dimensions.
*/
public static BufferedImage resizeCanvas(final BufferedImage image, final int newWidth, final int newHeight)
{
@@ -224,7 +240,7 @@ public class ImageUtil
*
* @param image The image to be rotated.
* @param theta The number of radians to rotate the image.
* @return The given image, rotated by the given theta.
* @return The given image, rotated by the given theta.
*/
public static BufferedImage rotateImage(final BufferedImage image, final double theta)
{
@@ -240,7 +256,7 @@ public class ImageUtil
* @param image The image to be flipped.
* @param horizontal Whether the image should be flipped horizontally.
* @param vertical Whether the image should be flipped vertically.
* @return The given image, flipped horizontally and/or vertically.
* @return The given image, flipped horizontally and/or vertically.
*/
public static BufferedImage flipImage(final BufferedImage image, final boolean horizontal, final boolean vertical)
{
@@ -275,7 +291,7 @@ public class ImageUtil
*
* @param image The image to be outlined.
* @param color The color to use for the outline.
* @return The BufferedImage with its edges outlined with the given color.
* @return The BufferedImage with its edges outlined with the given color.
*/
public static BufferedImage outlineImage(final BufferedImage image, final Color color)
{
@@ -289,7 +305,7 @@ public class ImageUtil
* @param image The image to be outlined.
* @param color The color to use for the outline.
* @param fillCondition The predicate to be consumed by {@link #fillImage(BufferedImage, Color, Predicate) fillImage(BufferedImage, Color, Predicate)}
* @return The BufferedImage with its edges outlined with the given color.
* @return The BufferedImage with its edges outlined with the given color.
*/
public static BufferedImage outlineImage(final BufferedImage image, final Color color, final Predicate<Color> fillCondition)
{
@@ -303,8 +319,8 @@ public class ImageUtil
* @param image The image to be outlined.
* @param color The color to use for the outline.
* @param outlineCorners Whether to draw an outline around corners, or only around edges.
* @return The BufferedImage with its edges--and optionally, corners--outlined
* with the given color.
* @return The BufferedImage with its edges--and optionally, corners--outlined
* with the given color.
*/
public static BufferedImage outlineImage(final BufferedImage image, final Color color, final Boolean outlineCorners)
{
@@ -319,8 +335,8 @@ public class ImageUtil
* @param color The color to use for the outline.
* @param fillCondition The predicate to be consumed by {@link #fillImage(BufferedImage, Color, Predicate) fillImage(BufferedImage, Color, Predicate)}
* @param outlineCorners Whether to draw an outline around corners, or only around edges.
* @return The BufferedImage with its edges--and optionally, corners--outlined
* with the given color.
* @return The BufferedImage with its edges--and optionally, corners--outlined
* with the given color.
*/
public static BufferedImage outlineImage(final BufferedImage image, final Color color, final Predicate<Color> fillCondition, final Boolean outlineCorners)
{
@@ -354,7 +370,7 @@ public class ImageUtil
*
* @param c The class to be referenced for resource path.
* @param path The path, relative to the given class.
* @return A {@link BufferedImage} of the loaded image resource from the given path.
* @return A {@link BufferedImage} of the loaded image resource from the given path.
*/
public static BufferedImage getResourceStreamFromClass(final Class c, final String path)
{
@@ -362,15 +378,16 @@ public class ImageUtil
{
synchronized (ImageIO.class)
{
try (InputStream in = c.getResourceAsStream(path))
{
return ImageIO.read(in);
}
return ImageIO.read(c.getResourceAsStream(path));
}
}
catch (IllegalArgumentException e)
{
throw new IllegalArgumentException(path, e);
}
catch (IOException e)
{
throw new RuntimeException(e);
throw new RuntimeException(path, e);
}
}
@@ -379,7 +396,7 @@ public class ImageUtil
*
* @param image The image which should have its non-transparent pixels filled.
* @param color The color with which to fill pixels.
* @return The given image with all non-transparent pixels set to the given color.
* @return The given image with all non-transparent pixels set to the given color.
*/
public static BufferedImage fillImage(final BufferedImage image, final Color color)
{
@@ -387,14 +404,14 @@ public class ImageUtil
}
/**
* Fills pixels of the given image with the given color based on a given fill condition
* predicate.
* Fills pixels of the given image with the given color based on a given fill condition
* predicate.
*
* @param image The image which should have its non-transparent pixels filled.
* @param color The color with which to fill pixels.
* @param fillCondition The condition on which to fill pixels with the given color.
* @return The given image with all pixels fulfilling the fill condition predicate
* set to the given color.
* @return The given image with all pixels fulfilling the fill condition predicate
* set to the given color.
*/
static BufferedImage fillImage(final BufferedImage image, final Color color, final Predicate<Color> fillCondition)
{
@@ -471,7 +488,7 @@ public class ImageUtil
* @param image The image to be adjusted.
* @param scales An array of scale operations to be performed on the image's color components.
* @param offsets An array of offset operations to be performed on the image's color components.
* @return The modified image after applying the given adjustments.
* @return The modified image after applying the given adjustments.
*/
private static BufferedImage offset(final BufferedImage image, final float[] scales, final float[] offsets)
{
@@ -481,10 +498,9 @@ public class ImageUtil
/**
* Converts the buffered image into a sprite image and returns it
*
* @param image The image to be converted
* @param client Current client instance
* @return The buffered image as a sprite image
* @return The buffered image as a sprite image
*/
public static Sprite getImageSprite(BufferedImage image, Client client)
{
@@ -516,12 +532,12 @@ public class ImageUtil
/**
* Converts an image into an {@code IndexedSprite} instance.
* <p>
*
* The passed in image can only have at max 255 different colors.
*
* @param image The image to be converted
* @param client Current client instance
* @return The image as an {@code IndexedSprite}
* @return The image as an {@code IndexedSprite}
*/
public static IndexedSprite getImageIndexedSprite(BufferedImage image, Client client)
{
@@ -713,4 +729,4 @@ public class ImageUtil
return result;
}
}
}

View File

@@ -32,6 +32,7 @@ import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Image;
import java.awt.Insets;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.MouseAdapter;
@@ -45,6 +46,7 @@ import java.util.function.BiConsumer;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.swing.ButtonModel;
import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
@@ -456,4 +458,18 @@ public class SwingUtil
SwingUtil.setFont(FontManager.getRunescapeFont());
}
}
public static void removeButtonDecorations(AbstractButton button)
{
button.setBorderPainted(false);
button.setContentAreaFilled(false);
button.setFocusPainted(false);
button.setMargin(new Insets(0, 0, 0, 0));
button.setOpaque(false);
}
public static void addModalTooltip(AbstractButton button, String on, String off)
{
button.addItemListener(l -> button.setToolTipText(button.isSelected() ? on : off));
}
}

View File

@@ -22,7 +22,7 @@
* (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.rs;
package net.runelite.client.util;
public class VerificationException extends Exception
{