Merge pull request #969 from sdburns1998/skillcalcv2

skillcalc: New UI and panel
This commit is contained in:
Tyler Bochard
2019-07-11 00:40:17 -04:00
committed by GitHub
30 changed files with 2708 additions and 2281 deletions

View File

@@ -1,675 +0,0 @@
/*
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.skillcalculator;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Singleton;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.Experience;
import net.runelite.api.Skill;
import net.runelite.client.game.ItemManager;
import net.runelite.client.plugins.skillcalculator.banked.CriticalItem;
import net.runelite.client.plugins.skillcalculator.banked.beans.Activity;
import net.runelite.client.plugins.skillcalculator.banked.beans.SecondaryItem;
import net.runelite.client.plugins.skillcalculator.banked.ui.CriticalItemPanel;
import net.runelite.client.plugins.skillcalculator.beans.SkillDataBonus;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.DynamicGridLayout;
import net.runelite.client.ui.FontManager;
@Slf4j
@Singleton
public class BankedCalculator extends JPanel
{
private static final DecimalFormat XP_FORMAT_COMMA = new DecimalFormat("#,###.#");
private final SkillCalculatorPanel parent;
private final Client client;
private final UICalculatorInputArea uiInput;
private final SkillCalculatorConfig config;
private final ItemManager itemManager;
private final CacheSkillData skillData = new CacheSkillData();
private final List<JCheckBox> bonusCheckBoxes = new ArrayList<>();
// UI Input data
private float xpFactor = 1.0f;
private CalculatorType currentCalc;
private Skill currentSkill;
private double totalBankedXp = 0.0f;
private final JLabel totalLabel = new JLabel();
private final JPanel detailConfigContainer;
private final JPanel detailContainer;
// Banked Experience magic
private Map<Integer, Integer> bankMap = new HashMap<>();
private final Map<String, Boolean> categoryMap = new HashMap<>(); // Check if CriticalItem Category is enabled
private final Map<CriticalItem, CriticalItemPanel> panelMap = new HashMap<>();
private final Map<CriticalItem, Integer> criticalMap = new HashMap<>(); // Quantity of CriticalItem inside bankMap
private final Map<CriticalItem, Activity> activityMap = new HashMap<>(); // Selected Activity used for calculating xp
private final Map<CriticalItem, Integer> linkedMap = new HashMap<>(); // ItemID of item that links to the CriticalItem
BankedCalculator(
final SkillCalculatorPanel parent,
final Client client,
final UICalculatorInputArea uiInput,
final SkillCalculatorConfig config,
final ItemManager itemManager)
{
this.parent = parent;
this.client = client;
this.uiInput = uiInput;
this.config = config;
this.itemManager = itemManager;
setLayout(new DynamicGridLayout(0, 1, 0, 5));
detailContainer = new JPanel();
detailContainer.setLayout(new BoxLayout(detailContainer, BoxLayout.Y_AXIS));
detailConfigContainer = new JPanel();
detailConfigContainer.setLayout(new BoxLayout(detailConfigContainer, BoxLayout.Y_AXIS));
}
private void reset()
{
criticalMap.clear();
linkedMap.clear();
xpFactor = 1f;
}
/**
* Update target Xp and Level inputs to match current Xp + total banked XP
*/
private void syncInputFields()
{
// Update Target XP & Level to include total banked xp
int newTotal = (int) (uiInput.getCurrentXPInput() + totalBankedXp);
uiInput.setTargetXPInput(newTotal);
uiInput.setTargetLevelInput(Experience.getLevelForXp(newTotal));
}
/*
* Banked Experience Logic
*/
/**
* Shows the Banked Xp tab for the CalculatorType
*
* @param calculatorType Selected Calculator Type
*/
void openBanked(CalculatorType calculatorType)
{
// clean slate for creating the required panel
removeAll();
reset();
if (calculatorType.getSkill() != currentSkill)
{
// Only clear Category and Activity map on skill change.
activityMap.clear();
categoryMap.clear();
}
currentCalc = calculatorType;
currentSkill = calculatorType.getSkill();
bankMap = parent.getBankMap();
uiInput.setCurrentLevelInput(client.getRealSkillLevel(currentSkill));
uiInput.setCurrentXPInput(client.getSkillExperience(currentSkill));
// Only adds Banked Experience portion if enabled for this SkillCalc and have seen their bank
if (!calculatorType.isBankedXpFlag())
{
add(new JLabel("<html><div style='text-align: center;'>Banked Experience is not enabled for this skill.</div></html>", JLabel.CENTER));
}
else if (bankMap.size() <= 0)
{
add(new JLabel("Please visit a bank!", JLabel.CENTER));
}
else
{
// Prevent editing of the target level/exp since we automagically adjust them
uiInput.getUiFieldTargetLevel().setEditable(false);
uiInput.getUiFieldTargetXP().setEditable(false);
// Now we can actually show the Banked Experience Panel
// Adds Config Options for this panel
renderBankedXpOptions();
renderBonusXpOptions();
// sprite 202
calculatedBankedMaps();
// Calculate total banked experience and create detail container
refreshDetailContainer();
// Add back all necessary content
add(detailConfigContainer);
add(totalLabel);
add(detailContainer);
}
revalidate();
repaint();
// Update the input fields.
syncInputFields();
}
/**
* Add the config options for toggling each Item Category
*/
private void renderBankedXpOptions()
{
Set<String> categories = CriticalItem.getSkillCategories(currentSkill);
if (categories == null)
{
return;
}
add(new JLabel("Configs:"));
for (String category : categories)
{
JPanel uiOption = new JPanel(new BorderLayout());
JLabel uiLabel = new JLabel(category);
JCheckBox uiCheckbox = new JCheckBox();
uiLabel.setForeground(Color.WHITE);
uiLabel.setFont(FontManager.getRunescapeSmallFont());
uiOption.setBorder(BorderFactory.createEmptyBorder(3, 7, 3, 0));
uiOption.setBackground(ColorScheme.DARKER_GRAY_COLOR);
// Everything is enabled by default
uiCheckbox.setSelected(true);
categoryMap.put(category, true);
// Adjust Total Banked XP check-state of the box.
uiCheckbox.addActionListener(e -> toggleCategory(category, uiCheckbox.isSelected()));
uiCheckbox.setBackground(ColorScheme.MEDIUM_GRAY_COLOR);
uiOption.add(uiLabel, BorderLayout.WEST);
uiOption.add(uiCheckbox, BorderLayout.EAST);
add(uiOption);
add(Box.createRigidArea(new Dimension(0, 5)));
}
}
/**
* Used to toggle Categories of Items inside the Banked Xp tab
*
* @param category Category Name
* @param enabled is enabled
*/
private void toggleCategory(String category, boolean enabled)
{
categoryMap.put(category, enabled);
refreshDetailContainer();
}
/**
* Creates the Maps used for easy access when calculating Banked Xp
*/
private void calculatedBankedMaps()
{
// Grab all CriticalItems for this skill
List<CriticalItem> items = CriticalItem.getBySkillName(currentSkill);
// Loop over all Critical Items for this skill and determine how many are in the bank
for (CriticalItem item : items)
{
Integer qty = bankMap.get(item.getItemID());
if (qty != null && qty > 0)
{
if (criticalMap.containsKey(item))
{
criticalMap.put(item, criticalMap.get(item) + qty);
}
else
{
criticalMap.put(item, qty);
}
// Ensure the item this is linked to maps back to us.
if (item.getLinkedItemId() != -1)
{
CriticalItem i = CriticalItem.getByItemId(item.getLinkedItemId());
if (i != null)
{
linkedMap.put(i, item.getItemID());
}
}
}
}
}
/**
* Populates the detailContainer with the necessary CriticalItemPanels
*/
private void refreshDetailContainer()
{
detailContainer.removeAll();
panelMap.clear();
Map<CriticalItem, Integer> map = getBankedXpBreakdown();
for (Map.Entry<CriticalItem, Integer> entry : map.entrySet())
{
CriticalItem item = entry.getKey();
createItemPanel(item);
}
detailContainer.revalidate();
detailContainer.repaint();
calculateBankedXpTotal();
}
/**
* Creates an Individual Item Panel if it should be displayed
*
* @param item CriticalItem this information is tied too
*/
private void createItemPanel(CriticalItem item)
{
// Category Included?
if (categoryMap.get(item.getCategory()))
{
// Get possible activities limited to current level
List<Activity> activities = Activity.getByCriticalItem(item, uiInput.getCurrentLevelInput());
// Check if this should count as another item.
if (item.getLinkedItemId() != -1)
{
// Ensure the linked item panel is created even if there are none in bank.
CriticalItem linked = CriticalItem.getByItemId(item.getLinkedItemId());
if (!criticalMap.containsKey(linked))
{
createItemPanel(linked);
}
// One activity and rewards no xp ignore.
if (activities.size() == 1 && activities.get(0).getXp() <= 0)
{
return;
}
}
// If it doesn't have any activities ignore it in the breakdown.
if (activities.size() <= 0)
{
return;
}
// Either this item has multiple activities or the single activity rewards xp, create the item panel.
// Determine xp rate for this item
Activity a = getSelectedActivity(item);
double activityXp = a == null ? 0 : a.getXp();
double xp = activityXp * (item.isIgnoreBonus() ? 1.0f : xpFactor);
int amount = 0;
// If it has linked items figure out the working total.
Map<CriticalItem, Integer> links = getLinkedTotalMap(item);
for (Integer num : links.values())
{
amount += num;
}
// Actually create the panel displaying banked experience for this item
CriticalItemPanel panel = new CriticalItemPanel(this, itemManager, item, xp, amount, links);
// Limit to Banked Secondaries
if (config.limitedBankedSecondaries() && a != null)
{
panel.updateAmount(limitToActivitySecondaries(a, amount), true);
panel.recalculate();
}
panelMap.put(item, panel);
detailContainer.add(panel);
}
}
/**
* Return the Activity the player selected for this Item. Defaults to First activity
*
* @param i CriticalItem to check for
* @return selected Activity
*/
public Activity getSelectedActivity(CriticalItem i)
{
// Pull from memory if available
Activity a = activityMap.get(i);
if (a != null)
{
return a;
}
// If not in memory select the first Activity and add to memory
List<Activity> activities = Activity.getByCriticalItem(i);
if (activities.size() == 0)
{
// If you can't find an activity it means this item must link to one and give 0 xp
return null;
}
Activity selected = activities.get(0);
activityMap.put(i, selected);
return selected;
}
/**
* Creates a Map of Item ID and QTY for this Skill by Category. Keeps order for better UI display
*
* @return Map of Item ID and QTY for this Skill by Category
*/
private Map<CriticalItem, Integer> getBankedXpBreakdown()
{
Map<CriticalItem, Integer> map = new LinkedHashMap<>();
for (String category : CriticalItem.getSkillCategories(currentSkill))
{
List<CriticalItem> items = CriticalItem.getItemsForSkillCategories(currentSkill, category);
for (CriticalItem item : items)
{
Integer amount = bankMap.get(item.getItemID());
if (amount != null && amount > 0)
{
map.put(item, amount);
}
}
}
return map;
}
/**
* Used to select an Activity for an item
*
* @param i CriticalItem
* @param a Activity selected
*/
public void activitySelected(CriticalItem i, Activity a)
{
// This is triggered on every click so don't update if activity didn't actually change
Activity cur = activityMap.get(i);
if (cur != null && cur.equals(a))
{
return;
}
// Update selected activity in map
activityMap.put(i, a);
// If had a previous selection and this item links to another check for item prevention change.
// If there are changes adjust the Linked panel quantity as well
if (cur != null && i.getLinkedItemId() != -1 && cur.isPreventLinked() != a.isPreventLinked())
{
CriticalItem linked = CriticalItem.getByItemId(i.getLinkedItemId());
CriticalItemPanel l = panelMap.get(linked);
if (l != null)
{
l.updateLinkedMap(getLinkedTotalMap(linked));
int amount = config.limitedBankedSecondaries() ? limitToActivitySecondaries(a, l.getAmount()) : l.getAmount();
l.updateAmount(amount, false);
l.recalculate();
}
}
// Total banked experience
CriticalItemPanel p = panelMap.get(i);
if (p != null)
{
p.updateLinkedMap(getLinkedTotalMap(i));
int amount = config.limitedBankedSecondaries() ? limitToActivitySecondaries(a, p.getAmount()) : p.getAmount();
p.updateAmount(amount, true);
p.updateXp(a.getXp() * (i.isIgnoreBonus() ? 1.0f : xpFactor));
}
// Update total banked xp value based on updated panels
calculateBankedXpTotal();
}
private Map<CriticalItem, Integer> getLinkedTotalMap(CriticalItem i)
{
return getLinkedTotalMap(i, true);
}
/**
* Creates a Map of CriticalItem and Qty for all items that link to the passed CriticalItem
*
* @param i CriticalItem to base Map off of
* @param first Since this is called recursively we want to ensure the original CriticalItem is always added
* @return Map of Linked CriticalItems and their Qty
*/
private Map<CriticalItem, Integer> getLinkedTotalMap(CriticalItem i, boolean first)
{
Map<CriticalItem, Integer> map = new LinkedHashMap<>();
if (!categoryMap.get(i.getCategory()))
{
return map;
}
// This item has an activity selected and its preventing linked functionality?
Activity selected = activityMap.get(i);
if (selected != null && selected.isPreventLinked()
// If initial request is for this item
&& !first)
{
return map;
}
// Add self to map
int amount = criticalMap.getOrDefault(i, 0);
if (amount > 0)
{
map.put(i, amount);
}
// This item doesn't link to anything, all done.
if (linkedMap.get(i) == null)
{
return map;
}
CriticalItem item = CriticalItem.getByItemId(linkedMap.get(i));
if (item == null)
{
log.warn("Error finding Critical Item for Item ID: {}", linkedMap.get(i));
return map;
}
map.putAll(getLinkedTotalMap(item, false));
return map;
}
/**
* SkillCalculatorPlugin sends the Bank Map when the bank contents change
*
* @param map Map of Item IDs and Quantity
*/
void updateBankMap(Map<Integer, Integer> map)
{
boolean oldMapFlag = (bankMap.size() <= 0);
bankMap = map;
// Refresh entire panel if old map was empty
if (oldMapFlag)
{
CalculatorType calc = CalculatorType.getBySkill(currentSkill);
SwingUtilities.invokeLater(() ->
{
if (calc != null)
{
openBanked(calc);
}
});
return;
}
// recalculate all data related to banked experience except for activity selections
criticalMap.clear();
linkedMap.clear();
calculatedBankedMaps();
// Update the Total XP banked and the details panel
SwingUtilities.invokeLater(this::refreshDetailContainer);
}
/**
* Loops over all ItemPanels too sum their total xp and updates the label with the new value
*/
private void calculateBankedXpTotal()
{
double total = 0.0;
for (CriticalItemPanel p : panelMap.values())
{
total += p.getTotal();
}
totalBankedXp = total;
syncBankedXp();
}
/**
* Used to update the UI to reflect the new Banked XP amount
*/
private void syncBankedXp()
{
totalLabel.setText("Total Banked xp: " + XP_FORMAT_COMMA.format(totalBankedXp));
syncInputFields();
revalidate();
repaint();
}
/**
* Check Bank for Activity Secondaries and Limits to possible Activity amounts
*
* @param a Selected Activity
* @param possible Amount of Critical Item available
* @return possible Limited to Banked Secondaries
*/
private int limitToActivitySecondaries(Activity a, int possible)
{
for (SecondaryItem i : a.getSecondaries())
{
int banked = bankMap.getOrDefault(i.getId(), 0);
int newPossible = banked / i.getQty();
possible = newPossible < possible ? newPossible : possible;
}
return possible;
}
/**
* Renders the Xp Modifier options
*/
private void renderBonusXpOptions()
{
SkillDataBonus[] bonuses = skillData.getSkillData(currentCalc.getDataFile()).getBonuses();
if (bonuses != null)
{
add(new JLabel("Bonus Experience:"));
for (SkillDataBonus bonus : bonuses)
{
JPanel checkboxPanel = buildCheckboxPanel(bonus);
add(checkboxPanel);
add(Box.createRigidArea(new Dimension(0, 5)));
}
}
}
private JPanel buildCheckboxPanel(SkillDataBonus bonus)
{
JPanel uiOption = new JPanel(new BorderLayout());
JLabel uiLabel = new JLabel(bonus.getName());
JCheckBox uiCheckbox = new JCheckBox();
uiLabel.setForeground(Color.WHITE);
uiLabel.setFont(FontManager.getRunescapeSmallFont());
uiOption.setBorder(BorderFactory.createEmptyBorder(3, 7, 3, 0));
uiOption.setBackground(ColorScheme.DARKER_GRAY_COLOR);
// Adjust XP bonus depending on check-state of the boxes.
uiCheckbox.addActionListener(event -> adjustCheckboxes(uiCheckbox, bonus));
uiCheckbox.setBackground(ColorScheme.MEDIUM_GRAY_COLOR);
uiOption.add(uiLabel, BorderLayout.WEST);
uiOption.add(uiCheckbox, BorderLayout.EAST);
bonusCheckBoxes.add(uiCheckbox);
return uiOption;
}
private void adjustCheckboxes(JCheckBox target, SkillDataBonus bonus)
{
adjustXPBonus(0);
bonusCheckBoxes.forEach(otherSelectedCheckbox ->
{
if (otherSelectedCheckbox != target)
{
otherSelectedCheckbox.setSelected(false);
}
});
if (target.isSelected())
{
adjustXPBonus(bonus.getValue());
}
}
private void adjustXPBonus(float value)
{
xpFactor = 1f + value;
refreshDetailContainer();
}
}

View File

@@ -35,7 +35,7 @@ class CacheSkillData
{
private final Map<String, SkillData> cache = new HashMap<>();
SkillData getSkillData(final String dataFile)
SkillData getSkillData(String dataFile)
{
if (cache.containsKey(dataFile))
{

View File

@@ -1,6 +1,5 @@
/*
* Copyright (c) 2018, Kruithne <kruithne@gmail.com>
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,47 +24,32 @@
*/
package net.runelite.client.plugins.skillcalculator;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.api.Skill;
@AllArgsConstructor
@Getter(AccessLevel.PACKAGE)
public enum CalculatorType
@Getter
enum CalculatorType
{
AGILITY(Skill.AGILITY, "skill_agility.json", false),
CONSTRUCTION(Skill.CONSTRUCTION, "skill_construction.json", true),
COOKING(Skill.COOKING, "skill_cooking.json", true),
CRAFTING(Skill.CRAFTING, "skill_crafting.json", true),
FARMING(Skill.FARMING, "skill_farming.json", true),
FIREMAKING(Skill.FIREMAKING, "skill_firemaking.json", false),
FLETCHING(Skill.FLETCHING, "skill_fletching.json", false),
FISHING(Skill.FISHING, "skill_fishing.json", false),
HERBLORE(Skill.HERBLORE, "skill_herblore.json", true),
HUNTER(Skill.HUNTER, "skill_hunter.json", false),
MAGIC(Skill.MAGIC, "skill_magic.json", false),
MINING(Skill.MINING, "skill_mining.json", false),
PRAYER(Skill.PRAYER, "skill_prayer.json", true),
RUNECRAFT(Skill.RUNECRAFT, "skill_runecraft.json", false),
SMITHING(Skill.SMITHING, "skill_smithing.json", true),
THIEVING(Skill.THIEVING, "skill_thieving.json", false),
WOODCUTTING(Skill.WOODCUTTING, "skill_woodcutting.json", false);
MINING(Skill.MINING, "skill_mining.json"),
AGILITY(Skill.AGILITY, "skill_agility.json"),
SMITHING(Skill.SMITHING, "skill_smithing.json"),
HERBLORE(Skill.HERBLORE, "skill_herblore.json"),
FISHING(Skill.FISHING, "skill_fishing.json"),
THIEVING(Skill.THIEVING, "skill_thieving.json"),
COOKING(Skill.COOKING, "skill_cooking.json"),
PRAYER(Skill.PRAYER, "skill_prayer.json"),
CRAFTING(Skill.CRAFTING, "skill_crafting.json"),
FIREMAKING(Skill.FIREMAKING, "skill_firemaking.json"),
MAGIC(Skill.MAGIC, "skill_magic.json"),
FLETCHING(Skill.FLETCHING, "skill_fletching.json"),
WOODCUTTING(Skill.WOODCUTTING, "skill_woodcutting.json"),
RUNECRAFT(Skill.RUNECRAFT, "skill_runecraft.json"),
FARMING(Skill.FARMING, "skill_farming.json"),
CONSTRUCTION(Skill.CONSTRUCTION, "skill_construction.json"),
HUNTER(Skill.HUNTER, "skill_hunter.json");
private final Skill skill;
private final String dataFile;
private final boolean bankedXpFlag;
public static CalculatorType getBySkill(Skill skill)
{
for (CalculatorType c : values())
{
if (c.getSkill().equals(skill))
{
return c;
}
}
return null;
}
}

View File

@@ -34,18 +34,13 @@ import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import javax.inject.Singleton;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import lombok.AccessLevel;
import lombok.Getter;
import net.runelite.api.Client;
import net.runelite.api.Experience;
import net.runelite.api.Skill;
import net.runelite.client.game.ItemManager;
import net.runelite.client.game.SpriteManager;
import net.runelite.client.plugins.skillcalculator.beans.SkillData;
@@ -59,7 +54,6 @@ import net.runelite.client.ui.components.IconTextField;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
@Singleton
class SkillCalculator extends JPanel
{
private static final int MAX_XP = 200_000_000;
@@ -71,9 +65,7 @@ class SkillCalculator extends JPanel
private final ItemManager itemManager;
private final List<UIActionSlot> uiActionSlots = new ArrayList<>();
private final CacheSkillData cacheSkillData = new CacheSkillData();
@Getter(AccessLevel.PACKAGE)
private final UICombinedActionSlot combinedActionSlot;
@Getter(AccessLevel.PACKAGE)
private final List<UIActionSlot> combinedActionSlots = new ArrayList<>();
private final List<JCheckBox> bonusCheckBoxes = new ArrayList<>();
private final IconTextField searchBar = new IconTextField();
@@ -85,9 +77,8 @@ class SkillCalculator extends JPanel
private int targetXP = Experience.getXpForLevel(targetLevel);
private float xpFactor = 1.0f;
private float lastBonus = 0.0f;
private CalculatorType calculatorType;
SkillCalculator(final Client client, final UICalculatorInputArea uiInput, final SpriteManager spriteManager, final ItemManager itemManager)
SkillCalculator(Client client, UICalculatorInputArea uiInput, SpriteManager spriteManager, ItemManager itemManager)
{
this.client = client;
this.uiInput = uiInput;
@@ -123,8 +114,6 @@ class SkillCalculator extends JPanel
void openCalculator(CalculatorType calculatorType)
{
this.calculatorType = calculatorType;
// Load the skill data.
skillData = cacheSkillData.getSkillData(calculatorType.getDataFile());
@@ -132,11 +121,10 @@ class SkillCalculator extends JPanel
xpFactor = 1.0f;
// Update internal skill/XP values.
updateInternalValues();
// BankedCalculator prevents these from being editable so just ensure they are editable.
uiInput.getUiFieldTargetLevel().setEditable(true);
uiInput.getUiFieldTargetXP().setEditable(true);
currentXP = client.getSkillExperience(calculatorType.getSkill());
currentLevel = Experience.getLevelForXp(currentXP);
targetLevel = enforceSkillBounds(currentLevel + 1);
targetXP = Experience.getXpForLevel(targetLevel);
// Remove all components (action slots) from this panel.
removeAll();
@@ -144,9 +132,6 @@ class SkillCalculator extends JPanel
// Clear the search bar
searchBar.setText(null);
// Clear the search bar
searchBar.setText(null);
// Add in checkboxes for available skill bonuses.
renderBonusOptions();
@@ -163,24 +148,6 @@ class SkillCalculator extends JPanel
updateInputFields();
}
private void updateInternalValues()
{
updateCurrentValues();
updateTargetValues();
}
private void updateCurrentValues()
{
currentXP = client.getSkillExperience(calculatorType.getSkill());
currentLevel = Experience.getLevelForXp(currentXP);
}
private void updateTargetValues()
{
targetLevel = enforceSkillBounds(currentLevel + 1);
targetXP = Experience.getXpForLevel(targetLevel);
}
private void updateCombinedAction()
{
int size = combinedActionSlots.size();
@@ -254,7 +221,7 @@ class SkillCalculator extends JPanel
JCheckBox uiCheckbox = new JCheckBox();
uiLabel.setForeground(Color.WHITE);
uiLabel.setFont(FontManager.getSmallFont(getFont()));
uiLabel.setFont(FontManager.getRunescapeSmallFont());
uiOption.setBorder(BorderFactory.createEmptyBorder(3, 7, 3, 0));
uiOption.setBackground(ColorScheme.DARKER_GRAY_COLOR);
@@ -270,7 +237,7 @@ class SkillCalculator extends JPanel
for (JCheckBox checkBox : uiCheckBoxList)
{
if (checkBox != null && !checkBox.equals(uiCheckBox))
if (checkBox != uiCheckBox)
{
checkBox.setSelected(false);
}
@@ -466,25 +433,4 @@ class SkillCalculator extends JPanel
return slot.getAction().getName().toLowerCase().contains(text.toLowerCase());
}
/**
* Updates the current skill calculator (if present)
* <p>
* This method is invoked by the {@link SkillCalculatorPlugin} event subscriber
* when an {@link ExperienceChanged} object is posted to the event bus
*/
void updateSkillCalculator(Skill skill)
{
// If the user has selected a calculator, update its fields
Optional.ofNullable(calculatorType).ifPresent(calc ->
{
if (skill.equals(calculatorType.getSkill()))
{
// Update our model "current" values
updateCurrentValues();
// Update the UI to reflect our new model
updateInputFields();
}
});
}
}

View File

@@ -32,24 +32,24 @@ import net.runelite.client.config.ConfigItem;
public interface SkillCalculatorConfig extends Config
{
@ConfigItem(
keyName = "showBankedXp",
name = "Show Banked xp Tab",
description = "Shows the Banked xp tab inside the Calculator Panel",
keyName = "enabledBankedXp",
name = "Add Banked XP Panel",
description = "Adds the Banked XP Panel to the side bar",
position = 0
)
default boolean showBankedXp()
{
return true;
return false;
}
@ConfigItem(
keyName = "limitedBankedSecondaries",
name = "Limit Banked xp to Secondaries",
description = "Limits the Banked xp shown based on secondaries banked as well",
keyName = "cascadeBankedXp",
name = "Include output items",
description = "Includes output items in the item quantity calculations",
position = 1
)
default boolean limitedBankedSecondaries()
default boolean cascadeBankedXp()
{
return false;
return true;
}
}

View File

@@ -1,7 +1,6 @@
/*
* Copyright (c) 2018, Kruithne <kruithne@gmail.com>
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,20 +29,10 @@ package net.runelite.client.plugins.skillcalculator;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.inject.Singleton;
import javax.swing.ImageIcon;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.Skill;
import net.runelite.client.game.ItemManager;
import net.runelite.client.game.SkillIconManager;
import net.runelite.client.game.SpriteManager;
@@ -52,43 +41,30 @@ import net.runelite.client.ui.PluginPanel;
import net.runelite.client.ui.components.materialtabs.MaterialTab;
import net.runelite.client.ui.components.materialtabs.MaterialTabGroup;
@Slf4j
@Singleton
class SkillCalculatorPanel extends PluginPanel
{
private final SkillCalculator uiCalculator;
private final SkillIconManager iconManager;
private final SkillCalculatorConfig config;
private final BankedCalculator bankedCalculator;
private CalculatorType currentCalc;
private final MaterialTabGroup skillGroup;
private final MaterialTabGroup tabGroup;
private String currentTab;
private final List<String> tabs = new ArrayList<>();
@Getter
private Map<Integer, Integer> bankMap = new HashMap<>();
private final GridBagConstraints c;
SkillCalculatorPanel(final SkillIconManager iconManager, final Client client, final SkillCalculatorConfig config, final SpriteManager spriteManager, final ItemManager itemManager)
SkillCalculatorPanel(SkillIconManager iconManager, Client client, SpriteManager spriteManager, ItemManager itemManager)
{
super();
getScrollPane().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
this.iconManager = iconManager;
this.config = config;
setBorder(new EmptyBorder(10, 10, 10, 10));
setLayout(new GridBagLayout());
c = new GridBagConstraints();
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridx = 0;
c.gridy = 0;
skillGroup = new MaterialTabGroup();
skillGroup.setLayout(new GridLayout(0, 6, 7, 7));
tabGroup = new MaterialTabGroup();
tabGroup.setLayout(new GridLayout(0, 6, 7, 7));
addCalculatorButtons();
@@ -97,23 +73,14 @@ class SkillCalculatorPanel extends PluginPanel
uiInput.setBackground(ColorScheme.DARK_GRAY_COLOR);
uiCalculator = new SkillCalculator(client, uiInput, spriteManager, itemManager);
bankedCalculator = new BankedCalculator(this, client, uiInput, config, itemManager);
tabGroup = new MaterialTabGroup();
tabGroup.setBorder(new EmptyBorder(0, 0, 10, 0));
addTabButtons();
add(skillGroup, c);
add(tabGroup, c);
c.gridy++;
add(uiInput, c);
c.gridy++;
add(tabGroup, c);
c.gridy++;
add(uiCalculator, c);
c.gridy++;
}
private void addCalculatorButtons()
@@ -121,126 +88,14 @@ class SkillCalculatorPanel extends PluginPanel
for (CalculatorType calculatorType : CalculatorType.values())
{
ImageIcon icon = new ImageIcon(iconManager.getSkillImage(calculatorType.getSkill(), true));
MaterialTab tab = new MaterialTab(icon, skillGroup, null);
MaterialTab tab = new MaterialTab(icon, tabGroup, null);
tab.setOnSelectEvent(() ->
{
if (currentCalc != null && currentCalc.equals(calculatorType))
{
return true;
}
currentCalc = calculatorType;
selectedTab(currentTab, true);
uiCalculator.openCalculator(calculatorType);
return true;
});
skillGroup.addTab(tab);
tabGroup.addTab(tab);
}
}
private void addTabButtons()
{
tabGroup.removeAll();
tabs.clear();
tabs.add("Calculator");
if (config.showBankedXp())
{
tabs.add("Banked Xp");
}
// Only show if both options are visible
tabGroup.setVisible(tabs.size() > 1);
tabGroup.setLayout(new GridLayout(0, tabs.size(), 7, 7));
for (String s : tabs)
{
MaterialTab matTab = new MaterialTab(s, tabGroup, null);
matTab.setHorizontalAlignment(SwingUtilities.CENTER);
// Ensure Background is applied
matTab.setOpaque(true);
matTab.setBackground(ColorScheme.DARKER_GRAY_COLOR);
// When Clicked
matTab.setOnSelectEvent(() ->
{
selectedTab(s, false);
return true;
});
tabGroup.addTab(matTab);
}
MaterialTab selected = tabGroup.getTab(0);
if (tabs.contains(currentTab))
{
selected = tabGroup.getTab(tabs.indexOf(currentTab));
}
tabGroup.select(selected);
currentTab = selected.getText();
}
private void selectedTab(String s, boolean force)
{
// Do not refresh the panel if they clicked the same tab, unless they selected a new skill
if (Objects.equals(currentTab, s) && !force)
{
return;
}
currentTab = s;
// Only open a panel if a skill is selected
if (currentCalc == null)
{
return;
}
switch (s)
{
case "Calculator":
remove(bankedCalculator);
add(uiCalculator, c);
uiCalculator.openCalculator(currentCalc);
break;
case "Banked Xp":
remove(uiCalculator);
add(bankedCalculator, c);
bankedCalculator.openBanked(currentCalc);
break;
}
this.revalidate();
this.repaint();
}
// Refresh entire panel
void refreshPanel()
{
// Recreate Tabs (in case of Config change) and selects the first tab
addTabButtons();
// Ensure reload
selectedTab(currentTab, true);
this.revalidate();
this.repaint();
}
// Wrapper function for updating SkillCalculator's bankMap
void updateBankMap(Map<Integer, Integer> bank)
{
bankMap = bank;
if (currentCalc != null & currentTab.equals("Banked Xp"))
{
bankedCalculator.updateBankMap(bankMap);
}
}
void updateSkillCalculator(Skill skill)
{
uiCalculator.updateSkillCalculator(skill);
}
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018, Kruithne <kruithne@gmail.com>
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,18 +31,13 @@ import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.swing.SwingUtilities;
import lombok.Getter;
import net.runelite.api.Client;
import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemContainer;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.ExperienceChanged;
import net.runelite.api.events.GameTick;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
@@ -51,7 +46,9 @@ import net.runelite.client.game.SkillIconManager;
import net.runelite.client.game.SpriteManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.skillcalculator.banked.CriticalItem;
import net.runelite.client.plugins.skillcalculator.banked.BankedCalculatorPanel;
import net.runelite.client.plugins.skillcalculator.banked.beans.Activity;
import net.runelite.client.plugins.skillcalculator.banked.beans.CriticalItem;
import net.runelite.client.ui.ClientToolbar;
import net.runelite.client.ui.NavigationButton;
import net.runelite.client.util.ImageUtil;
@@ -61,7 +58,6 @@ import net.runelite.client.util.ImageUtil;
description = "Enable the Skill Calculator panel",
tags = {"panel", "skilling"}
)
@Singleton
public class SkillCalculatorPlugin extends Plugin
{
@Inject
@@ -86,12 +82,10 @@ public class SkillCalculatorPlugin extends Plugin
private SkillCalculatorConfig skillCalculatorConfig;
private NavigationButton uiNavigationButton;
private SkillCalculatorPanel uiPanel;
private NavigationButton bankedUiNavigationButton;
@Getter
private Map<Integer, Integer> bankMap = new HashMap<>();
private int bankHash;
private BankedCalculatorPanel bankedUiPanel;
private int bankHash = -1;
@Provides
SkillCalculatorConfig getConfig(ConfigManager configManager)
@@ -103,7 +97,7 @@ public class SkillCalculatorPlugin extends Plugin
protected void startUp() throws Exception
{
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "calc.png");
this.uiPanel = new SkillCalculatorPanel(skillIconManager, client, skillCalculatorConfig, spriteManager, itemManager);
final SkillCalculatorPanel uiPanel = new SkillCalculatorPanel(skillIconManager, client, spriteManager, itemManager);
uiNavigationButton = NavigationButton.builder()
.tooltip("Skill Calculator")
@@ -114,56 +108,32 @@ public class SkillCalculatorPlugin extends Plugin
clientToolbar.addNavigation(uiNavigationButton);
clientThread.invokeLater(() ->
{
switch (client.getGameState())
{
case STARTING:
case UNKNOWN:
return false;
}
CriticalItem.prepareItemDefinitions(itemManager);
return true;
});
toggleBankedXpPanel();
}
@Override
protected void shutDown() throws Exception
{
clientToolbar.removeNavigation(uiNavigationButton);
bankMap.clear();
bankHash = -1;
if (bankedUiNavigationButton != null)
{
clientToolbar.removeNavigation(bankedUiNavigationButton);
}
}
@Subscribe
public void onConfigChanged(ConfigChanged event)
{
if (event.getGroup().equals("skillCalculator"))
if (event.getGroup().equals("skillCalculator") && event.getKey().equals("enabledBankedXp"))
{
if (event.getKey().equals("showBankedXp"))
{
bankMap.clear();
bankHash = -1;
}
SwingUtilities.invokeLater(() -> uiPanel.refreshPanel());
toggleBankedXpPanel();
}
}
// Pulled from bankvalue plugin to check if bank is open
@Subscribe
public void onGameTick(GameTick event)
public void onScriptCallbackEvent(ScriptCallbackEvent event)
{
if (!skillCalculatorConfig.showBankedXp())
{
return;
}
Widget widgetBankTitleBar = client.getWidget(WidgetInfo.BANK_TITLE_BAR);
// Don't update on a search because rs seems to constantly update the title
if (widgetBankTitleBar == null || widgetBankTitleBar.isHidden() || widgetBankTitleBar.getText().contains("Showing"))
if (!event.getEventName().equals("setBankTitle") || !skillCalculatorConfig.showBankedXp())
{
return;
}
@@ -171,54 +141,80 @@ public class SkillCalculatorPlugin extends Plugin
updateBankItems();
}
private void toggleBankedXpPanel()
{
if (skillCalculatorConfig.showBankedXp())
{
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "banked.png");
bankedUiPanel = new BankedCalculatorPanel(client, skillCalculatorConfig, skillIconManager, itemManager);
bankedUiNavigationButton = NavigationButton.builder()
.tooltip("Banked XP")
.icon(icon)
.priority(6)
.panel(bankedUiPanel)
.build();
clientToolbar.addNavigation(bankedUiNavigationButton);
clientThread.invoke(() ->
{
switch (client.getGameState())
{
case LOGIN_SCREEN:
case LOGIN_SCREEN_AUTHENTICATOR:
case LOGGING_IN:
case LOADING:
case LOGGED_IN:
case CONNECTION_LOST:
case HOPPING:
CriticalItem.prepareItemDefinitions(itemManager);
Activity.prepareItemDefinitions(itemManager);
return true;
default:
return false;
}
});
}
else
{
if (bankedUiNavigationButton == null)
{
return;
}
clientToolbar.removeNavigation(bankedUiNavigationButton);
bankedUiNavigationButton = null;
}
}
// Check if bank contents changed and if so send to UI
private void updateBankItems()
{
ItemContainer c = client.getItemContainer(InventoryID.BANK);
Item[] widgetItems = (c == null ? new Item[0] : c.getItems());
final ItemContainer c = client.getItemContainer(InventoryID.BANK);
if (c == null)
{
return;
}
// Couldn't find any items in bank, do nothing.
final Item[] widgetItems = c.getItems();
if (widgetItems == null || widgetItems.length == 0)
{
return;
}
Map<Integer, Integer> newBankMap = getBankMapIfDiff(widgetItems);
// Bank didn't change
if (newBankMap.size() == 0)
{
return;
}
bankMap = newBankMap;
// send updated bank map to ui
uiPanel.updateBankMap(bankMap);
}
// Recreates the bankMap and checks if the hashCode is different (the map has changed). Sends an empty map if no changes
private Map<Integer, Integer> getBankMapIfDiff(Item[] widgetItems)
{
Map<Integer, Integer> mapCheck = new HashMap<>();
final Map<Integer, Integer> m = new HashMap<>();
for (Item widgetItem : widgetItems)
{
mapCheck.put(widgetItem.getId(), widgetItem.getQuantity());
m.put(widgetItem.getId(), widgetItem.getQuantity());
}
int curHash = mapCheck.hashCode();
if (curHash != bankHash)
final int curHash = m.hashCode();
if (bankHash != curHash)
{
bankHash = curHash;
return mapCheck;
SwingUtilities.invokeLater(() -> bankedUiPanel.setBankMap(m));
}
return new HashMap<>();
}
@Subscribe
public void onExperienceChanged(ExperienceChanged changeEvent)
{
uiPanel.updateSkillCalculator(changeEvent.getSkill());
}
}

View File

@@ -33,7 +33,6 @@ import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.inject.Singleton;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
@@ -48,7 +47,6 @@ import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
@Singleton
class UIActionSlot extends JPanel
{
private static final Border GREEN_BORDER = new CompoundBorder(
@@ -127,7 +125,7 @@ class UIActionSlot extends JPanel
uiLabelName.setForeground(Color.WHITE);
uiLabelActions = new JShadowedLabel("Unknown");
uiLabelActions.setFont(FontManager.getSmallFont(getFont()));
uiLabelActions.setFont(FontManager.getRunescapeSmallFont());
uiLabelActions.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
uiInfo.add(uiLabelName);

View File

@@ -28,27 +28,24 @@ package net.runelite.client.plugins.skillcalculator;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import javax.inject.Singleton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import lombok.AccessLevel;
import lombok.Getter;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.components.FlatTextField;
@Getter(AccessLevel.PACKAGE)
@Singleton
class UICalculatorInputArea extends JPanel
@Getter
public class UICalculatorInputArea extends JPanel
{
private final JTextField uiFieldCurrentLevel;
private final JTextField uiFieldCurrentXP;
private final JTextField uiFieldTargetLevel;
private final JTextField uiFieldTargetXP;
UICalculatorInputArea()
public UICalculatorInputArea()
{
setLayout(new GridLayout(2, 2, 7, 7));
uiFieldCurrentLevel = addComponent("Current Level");
@@ -62,7 +59,7 @@ class UICalculatorInputArea extends JPanel
return getInput(uiFieldCurrentLevel);
}
void setCurrentLevelInput(int value)
public void setCurrentLevelInput(int value)
{
setInput(uiFieldCurrentLevel, value);
}
@@ -72,7 +69,7 @@ class UICalculatorInputArea extends JPanel
return getInput(uiFieldCurrentXP);
}
void setCurrentXPInput(Object value)
public void setCurrentXPInput(Object value)
{
setInput(uiFieldCurrentXP, value);
}
@@ -82,7 +79,7 @@ class UICalculatorInputArea extends JPanel
return getInput(uiFieldTargetLevel);
}
void setTargetLevelInput(Object value)
public void setTargetLevelInput(Object value)
{
setInput(uiFieldTargetLevel, value);
}
@@ -92,7 +89,7 @@ class UICalculatorInputArea extends JPanel
return getInput(uiFieldTargetXP);
}
void setTargetXPInput(Object value)
public void setTargetXPInput(Object value)
{
setInput(uiFieldTargetXP, value);
}
@@ -126,7 +123,7 @@ class UICalculatorInputArea extends JPanel
uiInput.setHoverBackgroundColor(ColorScheme.DARK_GRAY_HOVER_COLOR);
uiInput.setBorder(new EmptyBorder(5, 7, 5, 7));
uiLabel.setFont(FontManager.getSmallFont(getFont()));
uiLabel.setFont(FontManager.getRunescapeSmallFont());
uiLabel.setBorder(new EmptyBorder(0, 0, 4, 0));
uiLabel.setForeground(Color.WHITE);
@@ -137,4 +134,4 @@ class UICalculatorInputArea extends JPanel
return uiInput.getTextField();
}
}
}

View File

@@ -30,7 +30,6 @@ import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.inject.Singleton;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
@@ -40,14 +39,13 @@ import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
@Singleton
class UICombinedActionSlot extends JPanel
{
private static final Dimension ICON_SIZE = new Dimension(32, 32);
private final JShadowedLabel uiLabelActions;
private final JShadowedLabel uiLabelTitle;
UICombinedActionSlot(final SpriteManager spriteManager)
UICombinedActionSlot(SpriteManager spriteManager)
{
setLayout(new BorderLayout());
setBackground(ColorScheme.DARKER_GRAY_COLOR);
@@ -70,7 +68,7 @@ class UICombinedActionSlot extends JPanel
uiLabelTitle.setForeground(Color.WHITE);
uiLabelActions = new JShadowedLabel("Shift-click to select multiple");
uiLabelActions.setFont(FontManager.getSmallFont(getFont()));
uiLabelActions.setFont(FontManager.getRunescapeSmallFont());
uiLabelActions.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
uiInfo.add(uiLabelTitle);

View File

@@ -0,0 +1,462 @@
/*
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.skillcalculator.banked;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ItemEvent;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.Experience;
import net.runelite.api.Skill;
import net.runelite.client.game.AsyncBufferedImage;
import net.runelite.client.game.ItemManager;
import net.runelite.client.plugins.skillcalculator.SkillCalculatorConfig;
import net.runelite.client.plugins.skillcalculator.UICalculatorInputArea;
import net.runelite.client.plugins.skillcalculator.banked.beans.Activity;
import net.runelite.client.plugins.skillcalculator.banked.beans.BankedItem;
import net.runelite.client.plugins.skillcalculator.banked.beans.CriticalItem;
import net.runelite.client.plugins.skillcalculator.banked.beans.XpModifiers;
import net.runelite.client.plugins.skillcalculator.banked.components.GridItem;
import net.runelite.client.plugins.skillcalculator.banked.components.ModifyPanel;
import net.runelite.client.plugins.skillcalculator.banked.components.SelectionGrid;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.DynamicGridLayout;
import net.runelite.client.ui.FontManager;
@Slf4j
public class BankedCalculator extends JPanel
{
public static final DecimalFormat XP_FORMAT_COMMA = new DecimalFormat("#,###.#");
private final Client client;
@Getter
private final SkillCalculatorConfig config;
private final UICalculatorInputArea uiInput;
private final ItemManager itemManager;
// Some activities output a CriticalItem and may need to be included in the calculable qty
// Using multimap for cases where there are multiple items linked directly to one item, use recursion for otherwise
private final Multimap<CriticalItem, BankedItem> linkedMap = ArrayListMultimap.create();
private final Map<CriticalItem, BankedItem> bankedItemMap = new LinkedHashMap<>();
private final JLabel totalXpLabel = new JLabel();
private final ModifyPanel modifyPanel;
private SelectionGrid itemGrid;
@Setter
private Map<Integer, Integer> bankMap = new HashMap<>();
@Getter
private Skill currentSkill;
@Getter
private int skillLevel, skillExp, endLevel, endExp;
private final Collection<JCheckBox> xpModifierButtons = new ArrayList<>();
@Getter
private float xpFactor = 1.0f;
BankedCalculator(UICalculatorInputArea uiInput, Client client, SkillCalculatorConfig config, ItemManager itemManager)
{
this.uiInput = uiInput;
this.client = client;
this.config = config;
this.itemManager = itemManager;
setLayout(new DynamicGridLayout(0, 1, 0, 5));
// Panel used to modify banked item values
this.modifyPanel = new ModifyPanel(this, itemManager);
}
/**
* opens the Banked Calculator for this skill
*/
void open(final Skill newSkill)
{
if (newSkill.equals(currentSkill))
{
return;
}
this.currentSkill = newSkill;
removeAll();
xpFactor = 1.0f;
if (bankMap.size() <= 0)
{
add(new JLabel("Please visit a bank!", JLabel.CENTER));
revalidate();
repaint();
return;
}
skillLevel = client.getRealSkillLevel(currentSkill);
skillExp = client.getSkillExperience(currentSkill);
endLevel = skillLevel;
endExp = skillExp;
uiInput.setCurrentLevelInput(skillLevel);
uiInput.setCurrentXPInput(skillExp);
uiInput.setTargetLevelInput(endLevel);
uiInput.setTargetXPInput(endExp);
recreateBankedItemMap();
final Collection<XpModifiers> modifiers = XpModifiers.getModifiersBySkill(this.currentSkill);
for (final XpModifiers modifier : modifiers)
{
JPanel uiOption = new JPanel(new BorderLayout());
JLabel uiLabel = new JLabel(modifier.getName());
JCheckBox btn = new JCheckBox();
uiLabel.setForeground(Color.WHITE);
uiLabel.setFont(FontManager.getRunescapeSmallFont());
uiLabel.setHorizontalAlignment(SwingConstants.CENTER);
uiOption.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 0));
uiOption.setBackground(ColorScheme.DARKER_GRAY_COLOR);
btn.addItemListener((event) ->
{
switch (event.getStateChange())
{
case ItemEvent.DESELECTED:
xpFactor = 1.0f;
break;
case ItemEvent.SELECTED:
// Deselects all but the current item
final JCheckBox box = (JCheckBox) event.getItem();
xpModifierButtons.forEach(b -> b.setSelected(b == box));
xpFactor = modifier.getModifier();
break;
default:
return;
}
modifierUpdated();
});
xpModifierButtons.add(btn);
uiOption.add(uiLabel, BorderLayout.WEST);
uiOption.add(btn, BorderLayout.EAST);
add(uiOption);
}
recreateItemGrid();
// This should only be null if there are no items in their bank for this skill
if (itemGrid.getSelectedItem() == null)
{
add(new JLabel("Couldn't find any items for this skill.", JLabel.CENTER));
}
else
{
add(totalXpLabel);
add(modifyPanel);
add(itemGrid);
}
revalidate();
repaint();
}
private void recreateBankedItemMap()
{
bankedItemMap.clear();
linkedMap.clear();
final Collection<CriticalItem> items = CriticalItem.getBySkill(currentSkill);
log.debug("Critical Items for the {} Skill: {}", currentSkill.getName(), items);
for (final CriticalItem item : items)
{
final BankedItem banked = new BankedItem(item, bankMap.getOrDefault(item.getItemID(), 0));
bankedItemMap.put(item, banked);
Activity a = item.getSelectedActivity();
if (a == null)
{
final List<Activity> activities = Activity.getByCriticalItem(item);
if (activities.size() == 0)
{
continue;
}
item.setSelectedActivity(activities.get(0));
a = activities.get(0);
}
if (a.getLinkedItem() != null)
{
linkedMap.put(a.getLinkedItem(), banked);
}
}
log.debug("Banked Item Map: {}", bankedItemMap);
log.debug("Linked Map: {}", linkedMap);
}
/**
* Populates the detailContainer with the necessary BankedItemPanels
*/
private void recreateItemGrid()
{
// Selection grid will only display values with > 0 items
itemGrid = new SelectionGrid(this, bankedItemMap.values(), itemManager);
itemGrid.setOnSelectEvent(() ->
{
modifyPanel.setBankedItem(itemGrid.getSelectedItem());
return true;
});
itemGrid.setOnIgnoreEvent(() ->
{
CriticalItem item = itemGrid.getLastIgnoredItem().getItem();
updateLinkedItems(item.getSelectedActivity());
calculateBankedXpTotal();
return true;
});
// Select the first item in the list
modifyPanel.setBankedItem(itemGrid.getSelectedItem());
calculateBankedXpTotal();
}
public double getItemXpRate(final BankedItem bankedItem)
{
return bankedItem.getXpRate() * (bankedItem.getItem().isIgnoreBonus() ? 1.0f : xpFactor);
}
/**
* Calculates total item quantity accounting for backwards linked items
*
* @param item starting item
* @return item qty including linked items
*/
public int getItemQty(final BankedItem item)
{
int qty = item.getQty();
if (!config.cascadeBankedXp())
{
return qty;
}
final Map<CriticalItem, Integer> linked = createLinksMap(item);
final int linkedQty = linked.values().stream().mapToInt(Integer::intValue).sum();
return qty + linkedQty;
}
private void calculateBankedXpTotal()
{
double total = 0.0;
for (final GridItem i : itemGrid.getPanelMap().values())
{
if (i.isIgnored())
{
continue;
}
final BankedItem bi = i.getBankedItem();
total += getItemQty(bi) * getItemXpRate(bi);
}
endExp = (int) (skillExp + total);
endLevel = Experience.getLevelForXp(endExp);
totalXpLabel.setText("Total Banked xp: " + XP_FORMAT_COMMA.format(total));
uiInput.setTargetLevelInput(endLevel);
uiInput.setTargetXPInput(Math.min(Experience.MAX_SKILL_XP, endExp));
revalidate();
repaint();
}
/**
* Used to select an Activity for an item
*
* @param i BankedItem item the activity is tied to
* @param a Activity the selected activity
*/
public void activitySelected(final BankedItem i, final Activity a)
{
final CriticalItem item = i.getItem();
final Activity old = item.getSelectedActivity();
if (a.equals(old))
{
return;
}
item.setSelectedActivity(a);
// Cascade activity changes if necessary.
if (config.cascadeBankedXp() && (old.getLinkedItem() != a.getLinkedItem()))
{
// Update Linked Map
linkedMap.remove(old.getLinkedItem(), i);
linkedMap.put(a.getLinkedItem(), i);
// Update all items the old activity effects
updateLinkedItems(old);
// Update all the items the new activity effects
updateLinkedItems(a);
}
modifyPanel.setBankedItem(i);
itemGrid.getPanelMap().get(i).updateToolTip();
// recalculate total xp
calculateBankedXpTotal();
}
/**
* Updates the item quantities of all forward linked items
*
* @param activity the starting {@link Activity} to start the cascade from
*/
private void updateLinkedItems(final Activity activity)
{
if (activity == null)
{
return;
}
boolean foundSelected = false;
boolean panelAmountChange = false;
CriticalItem i = activity.getLinkedItem();
while (i != null)
{
final BankedItem bi = bankedItemMap.get(i);
if (bi == null)
{
break;
}
final int qty = getItemQty(bi);
final boolean stackable = bi.getItem().getItemInfo().isStackable() || qty > 1;
final AsyncBufferedImage img = itemManager.getImage(bi.getItem().getItemID(), qty, stackable);
final GridItem gridItem = itemGrid.getPanelMap().get(bi);
final int oldQty = gridItem.getAmount();
panelAmountChange = panelAmountChange || ((oldQty == 0 && qty > 0) || (oldQty > 0 && qty == 0));
gridItem.updateIcon(img, qty);
gridItem.updateToolTip();
foundSelected = foundSelected || itemGrid.getSelectedItem().equals(bi);
final Activity a = bi.getItem().getSelectedActivity();
if (a == null)
{
break;
}
i = a.getLinkedItem();
}
if (panelAmountChange)
{
itemGrid.refreshGridDisplay();
}
if (foundSelected)
{
// Refresh current modify panel if the cascade effects it
modifyPanel.setBankedItem(itemGrid.getSelectedItem());
}
}
/**
* Creates a Map of CriticalItem to bank qty for all items that are being linked to this one
*
* @param item starting item
* @return Map of CriticalItem to bank qty
*/
public Map<CriticalItem, Integer> createLinksMap(final BankedItem item)
{
final Map<CriticalItem, Integer> qtyMap = new HashMap<>();
final Activity a = item.getItem().getSelectedActivity();
if (a == null)
{
return qtyMap;
}
final Collection<BankedItem> linkedBank = linkedMap.get(item.getItem());
if (linkedBank == null || linkedBank.size() == 0)
{
return qtyMap;
}
for (final BankedItem linked : linkedBank)
{
// Check if the item is ignored in the grid
if (itemGrid != null)
{
final GridItem grid = itemGrid.getPanelMap().get(linked);
if (grid != null && grid.isIgnored())
{
continue;
}
}
final int qty = linked.getQty();
if (qty > 0)
{
qtyMap.put(linked.getItem(), qty);
}
qtyMap.putAll(createLinksMap(linked));
}
return qtyMap;
}
private void modifierUpdated()
{
itemGrid.getPanelMap().values().forEach(GridItem::updateToolTip);
modifyPanel.setBankedItem(modifyPanel.getBankedItem());
calculateBankedXpTotal();
}
}

View File

@@ -0,0 +1,120 @@
/*
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.skillcalculator.banked;
import com.google.common.collect.ImmutableSet;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ItemEvent;
import java.awt.image.BufferedImage;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.border.EmptyBorder;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.Skill;
import net.runelite.client.game.ItemManager;
import net.runelite.client.game.SkillIconManager;
import net.runelite.client.plugins.skillcalculator.SkillCalculatorConfig;
import net.runelite.client.plugins.skillcalculator.UICalculatorInputArea;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.PluginPanel;
import net.runelite.client.ui.components.ComboBoxIconEntry;
import net.runelite.client.ui.components.ComboBoxListRenderer;
@Slf4j
public class BankedCalculatorPanel extends PluginPanel
{
private final static ImmutableSet<Skill> BANKABLE_SKILLS = ImmutableSet.of(
Skill.CONSTRUCTION, Skill.COOKING, Skill.CRAFTING, Skill.FARMING, Skill.HERBLORE, Skill.PRAYER, Skill.SMITHING
);
private final BankedCalculator calculator;
public BankedCalculatorPanel(Client client, SkillCalculatorConfig config, SkillIconManager skillIconManager, ItemManager itemManager)
{
super();
setBorder(new EmptyBorder(10, 10, 10, 10));
setLayout(new GridBagLayout());
final UICalculatorInputArea inputs = new UICalculatorInputArea();
inputs.setBorder(new EmptyBorder(15, 0, 15, 0));
inputs.setBackground(ColorScheme.DARK_GRAY_COLOR);
inputs.getUiFieldTargetXP().setEditable(false);
inputs.getUiFieldTargetLevel().setEditable(false);
calculator = new BankedCalculator(inputs, client, config, itemManager);
// Create the Skill dropdown with icons
final JComboBox<ComboBoxIconEntry> dropdown = new JComboBox<>();
final ComboBoxListRenderer renderer = new ComboBoxListRenderer();
renderer.setDefaultText("Select a Skill...");
dropdown.setRenderer(renderer);
for (final Skill skill : BANKABLE_SKILLS)
{
final BufferedImage img = skillIconManager.getSkillImage(skill, true);
final ComboBoxIconEntry entry = new ComboBoxIconEntry(new ImageIcon(img), skill.getName(), skill);
dropdown.addItem(entry);
}
// Add click event handler now to prevent above code from triggering it.
dropdown.addItemListener(e ->
{
if (e.getStateChange() == ItemEvent.SELECTED)
{
final ComboBoxIconEntry source = (ComboBoxIconEntry) e.getItem();
if (source.getData() instanceof Skill)
{
final Skill skill = (Skill) source.getData();
this.calculator.open(skill);
}
}
});
dropdown.setSelectedIndex(-1);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridx = 0;
c.gridy = 0;
add(dropdown, c);
c.gridy++;
add(inputs, c);
c.gridy++;
add(calculator, c);
}
public void setBankMap(final Map<Integer, Integer> bankMap)
{
calculator.setBankMap(bankMap);
}
}

View File

@@ -1,418 +0,0 @@
/*
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.skillcalculator.banked;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import lombok.Getter;
import net.runelite.api.ItemDefinition;
import net.runelite.api.ItemID;
import net.runelite.api.Skill;
import net.runelite.client.game.ItemManager;
public enum CriticalItem
{
/**
* Construction Items
*/
// Planks
PLANK(ItemID.PLANK, "Planks", Skill.CONSTRUCTION),
OAK_PLANK(ItemID.OAK_PLANK, "Planks", Skill.CONSTRUCTION),
TEAK_PLANK(ItemID.TEAK_PLANK, "Planks", Skill.CONSTRUCTION),
MAHOGANY_PLANK(ItemID.MAHOGANY_PLANK, "Planks", Skill.CONSTRUCTION),
// Logs
LOGS(ItemID.LOGS, "Logs", Skill.CONSTRUCTION, ItemID.PLANK),
OAK_LOGS(ItemID.OAK_LOGS, "Logs", Skill.CONSTRUCTION, ItemID.OAK_PLANK),
TEAK_LOGS(ItemID.TEAK_LOGS, "Logs", Skill.CONSTRUCTION, ItemID.TEAK_PLANK),
MAHOGANY_LOGS(ItemID.MAHOGANY_LOGS, "Logs", Skill.CONSTRUCTION, ItemID.MAHOGANY_PLANK),
/**
* Herblore Items
*/
// Grimy Herbs
GRIMY_GUAM_LEAF(ItemID.GRIMY_GUAM_LEAF, "Grimy Herbs", Skill.HERBLORE, ItemID.GUAM_LEAF),
GRIMY_MARRENTILL(ItemID.GRIMY_MARRENTILL, "Grimy Herbs", Skill.HERBLORE, ItemID.MARRENTILL),
GRIMY_TARROMIN(ItemID.GRIMY_TARROMIN, "Grimy Herbs", Skill.HERBLORE, ItemID.TARROMIN),
GRIMY_HARRALANDER(ItemID.GRIMY_HARRALANDER, "Grimy Herbs", Skill.HERBLORE, ItemID.HARRALANDER),
GRIMY_RANARR_WEED(ItemID.GRIMY_RANARR_WEED, "Grimy Herbs", Skill.HERBLORE, ItemID.RANARR_WEED),
GRIMY_TOADFLAX(ItemID.GRIMY_TOADFLAX, "Grimy Herbs", Skill.HERBLORE, ItemID.TOADFLAX),
GRIMY_IRIT_LEAF(ItemID.GRIMY_IRIT_LEAF, "Grimy Herbs", Skill.HERBLORE, ItemID.IRIT_LEAF),
GRIMY_AVANTOE(ItemID.GRIMY_AVANTOE, "Grimy Herbs", Skill.HERBLORE, ItemID.AVANTOE),
GRIMY_KWUARM(ItemID.GRIMY_KWUARM, "Grimy Herbs", Skill.HERBLORE, ItemID.KWUARM),
GRIMY_SNAPDRAGON(ItemID.GRIMY_SNAPDRAGON, "Grimy Herbs", Skill.HERBLORE, ItemID.SNAPDRAGON),
GRIMY_CADANTINE(ItemID.GRIMY_CADANTINE, "Grimy Herbs", Skill.HERBLORE, ItemID.CADANTINE),
GRIMY_LANTADYME(ItemID.GRIMY_LANTADYME, "Grimy Herbs", Skill.HERBLORE, ItemID.LANTADYME),
GRIMY_DWARF_WEED(ItemID.GRIMY_DWARF_WEED, "Grimy Herbs", Skill.HERBLORE, ItemID.DWARF_WEED),
GRIMY_TORSTOL(ItemID.GRIMY_TORSTOL, "Grimy Herbs", Skill.HERBLORE, ItemID.TORSTOL),
// Clean Herbs
GUAM_LEAF(ItemID.GUAM_LEAF, "Cleaned Herbs", Skill.HERBLORE, ItemID.GUAM_POTION_UNF),
MARRENTILL(ItemID.MARRENTILL, "Cleaned Herbs", Skill.HERBLORE, ItemID.MARRENTILL_POTION_UNF),
TARROMIN(ItemID.TARROMIN, "Cleaned Herbs", Skill.HERBLORE, ItemID.TARROMIN_POTION_UNF),
HARRALANDER(ItemID.HARRALANDER, "Cleaned Herbs", Skill.HERBLORE, ItemID.HARRALANDER_POTION_UNF),
RANARR_WEED(ItemID.RANARR_WEED, "Cleaned Herbs", Skill.HERBLORE, ItemID.RANARR_POTION_UNF),
TOADFLAX(ItemID.TOADFLAX, "Cleaned Herbs", Skill.HERBLORE, ItemID.TOADFLAX_POTION_UNF),
IRIT_LEAF(ItemID.IRIT_LEAF, "Cleaned Herbs", Skill.HERBLORE, ItemID.IRIT_POTION_UNF),
AVANTOE(ItemID.AVANTOE, "Cleaned Herbs", Skill.HERBLORE, ItemID.AVANTOE_POTION_UNF),
KWUARM(ItemID.KWUARM, "Cleaned Herbs", Skill.HERBLORE, ItemID.KWUARM_POTION_UNF),
SNAPDRAGON(ItemID.SNAPDRAGON, "Cleaned Herbs", Skill.HERBLORE, ItemID.SNAPDRAGON_POTION_UNF),
CADANTINE(ItemID.CADANTINE, "Cleaned Herbs", Skill.HERBLORE, ItemID.CADANTINE_POTION_UNF),
LANTADYME(ItemID.LANTADYME, "Cleaned Herbs", Skill.HERBLORE, ItemID.LANTADYME_POTION_UNF),
DWARF_WEED(ItemID.DWARF_WEED, "Cleaned Herbs", Skill.HERBLORE, ItemID.DWARF_WEED_POTION_UNF),
TORSTOL(ItemID.TORSTOL, "Cleaned Herbs", Skill.HERBLORE, ItemID.TORSTOL_POTION_UNF),
// Unfinished Potions
GUAM_LEAF_POTION_UNF(ItemID.GUAM_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
MARRENTILL_POTION_UNF(ItemID.MARRENTILL_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
TARROMIN_POTION_UNF(ItemID.TARROMIN_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
HARRALANDER_POTION_UNF(ItemID.HARRALANDER_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
RANARR_POTION_UNF(ItemID.RANARR_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
TOADFLAX_POTION_UNF(ItemID.TOADFLAX_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
IRIT_POTION_UNF(ItemID.IRIT_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
AVANTOE_POTION_UNF(ItemID.AVANTOE_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
KWUARM_POTION_UNF(ItemID.KWUARM_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
SNAPDRAGON_POTION_UNF(ItemID.SNAPDRAGON_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
CADANTINE_POTION_UNF(ItemID.CADANTINE_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
LANTADYME_POTION_UNF(ItemID.LANTADYME_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
DWARF_WEED_POTION_UNF(ItemID.DWARF_WEED_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
TORSTOL_POTION_UNF(ItemID.TORSTOL_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
/**
* Prayer Items
*/
// Bones
BONES(ItemID.BONES, "Bones", Skill.PRAYER),
WOLF_BONES(ItemID.WOLF_BONES, "Bones", Skill.PRAYER),
BURNT_BONES(ItemID.BURNT_BONES, "Bones", Skill.PRAYER),
MONKEY_BONES(ItemID.MONKEY_BONES, "Bones", Skill.PRAYER),
BAT_BONES(ItemID.BAT_BONES, "Bones", Skill.PRAYER),
JOGRE_BONES(ItemID.JOGRE_BONES, "Bones", Skill.PRAYER),
BIG_BONES(ItemID.BIG_BONES, "Bones", Skill.PRAYER),
ZOGRE_BONES(ItemID.ZOGRE_BONES, "Bones", Skill.PRAYER),
SHAIKAHAN_BONES(ItemID.SHAIKAHAN_BONES, "Bones", Skill.PRAYER),
BABYDRAGON_BONES(ItemID.BABYDRAGON_BONES, "Bones", Skill.PRAYER),
WYVERN_BONES(ItemID.WYVERN_BONES, "Bones", Skill.PRAYER),
DRAGON_BONES(ItemID.DRAGON_BONES, "Bones", Skill.PRAYER),
FAYRG_BONES(ItemID.FAYRG_BONES, "Bones", Skill.PRAYER),
LAVA_DRAGON_BONES(ItemID.LAVA_DRAGON_BONES, "Bones", Skill.PRAYER),
RAURG_BONES(ItemID.RAURG_BONES, "Bones", Skill.PRAYER),
DAGANNOTH_BONES(ItemID.DAGANNOTH_BONES, "Bones", Skill.PRAYER),
OURG_BONES(ItemID.OURG_BONES, "Bones", Skill.PRAYER),
SUPERIOR_DRAGON_BONES(ItemID.SUPERIOR_DRAGON_BONES, "Bones", Skill.PRAYER),
// Shade Remains (Pyre Logs)
LOAR_REMAINS(ItemID.LOAR_REMAINS, "Shades", Skill.PRAYER, true),
PHRIN_REMAINS(ItemID.PHRIN_REMAINS, "Shades", Skill.PRAYER, true),
RIYL_REMAINS(ItemID.RIYL_REMAINS, "Shades", Skill.PRAYER, true),
ASYN_REMAINS(ItemID.ASYN_REMAINS, "Shades", Skill.PRAYER, true),
FIYR_REMAINS(ItemID.FIYR_REMAINS, "Shades", Skill.PRAYER, true),
// Ensouled Heads
ENSOULED_GOBLIN_HEAD(ItemID.ENSOULED_GOBLIN_HEAD_13448, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_MONKEY_HEAD(ItemID.ENSOULED_MONKEY_HEAD_13451, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_IMP_HEAD(ItemID.ENSOULED_IMP_HEAD_13454, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_MINOTAUR_HEAD(ItemID.ENSOULED_MINOTAUR_HEAD_13457, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_SCORPION_HEAD(ItemID.ENSOULED_SCORPION_HEAD_13460, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_BEAR_HEAD(ItemID.ENSOULED_BEAR_HEAD_13463, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_UNICORN_HEAD(ItemID.ENSOULED_UNICORN_HEAD_13466, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_DOG_HEAD(ItemID.ENSOULED_DOG_HEAD_13469, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_CHAOS_DRUID_HEAD(ItemID.ENSOULED_CHAOS_DRUID_HEAD_13472, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_GIANT_HEAD(ItemID.ENSOULED_GIANT_HEAD_13475, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_OGRE_HEAD(ItemID.ENSOULED_OGRE_HEAD_13478, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_ELF_HEAD(ItemID.ENSOULED_ELF_HEAD_13481, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_TROLL_HEAD(ItemID.ENSOULED_TROLL_HEAD_13484, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_HORROR_HEAD(ItemID.ENSOULED_HORROR_HEAD_13487, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_KALPHITE_HEAD(ItemID.ENSOULED_KALPHITE_HEAD_13490, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_DAGANNOTH_HEAD(ItemID.ENSOULED_DAGANNOTH_HEAD_13493, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_BLOODVELD_HEAD(ItemID.ENSOULED_BLOODVELD_HEAD_13496, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_TZHAAR_HEAD(ItemID.ENSOULED_TZHAAR_HEAD_13499, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_DEMON_HEAD(ItemID.ENSOULED_DEMON_HEAD_13502, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_AVIANSIE_HEAD(ItemID.ENSOULED_AVIANSIE_HEAD_13505, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_ABYSSAL_HEAD(ItemID.ENSOULED_ABYSSAL_HEAD_13508, "Ensouled Heads", Skill.PRAYER, true),
ENSOULED_DRAGON_HEAD(ItemID.ENSOULED_DRAGON_HEAD_13511, "Ensouled Heads", Skill.PRAYER, true),
/**
* Cooking Items
*/
RAW_HERRING(ItemID.RAW_HERRING, "Fish", Skill.COOKING),
RAW_MACKEREL(ItemID.RAW_MACKEREL, "Fish", Skill.COOKING),
RAW_TROUT(ItemID.RAW_TROUT, "Fish", Skill.COOKING),
RAW_COD(ItemID.RAW_COD, "Fish", Skill.COOKING),
RAW_PIKE(ItemID.RAW_PIKE, "Fish", Skill.COOKING),
RAW_SALMON(ItemID.RAW_SALMON, "Fish", Skill.COOKING),
RAW_TUNA(ItemID.RAW_TUNA, "Fish", Skill.COOKING),
RAW_KARAMBWAN(ItemID.RAW_KARAMBWAN, "Fish", Skill.COOKING),
RAW_LOBSTER(ItemID.RAW_LOBSTER, "Fish", Skill.COOKING),
RAW_BASS(ItemID.RAW_BASS, "Fish", Skill.COOKING),
RAW_SWORDFISH(ItemID.RAW_SWORDFISH, "Fish", Skill.COOKING),
RAW_MONKFISH(ItemID.RAW_MONKFISH, "Fish", Skill.COOKING),
RAW_SHARK(ItemID.RAW_SHARK, "Fish", Skill.COOKING),
RAW_SEA_TURTLE(ItemID.RAW_SEA_TURTLE, "Fish", Skill.COOKING),
RAW_ANGLERFISH(ItemID.RAW_ANGLERFISH, "Fish", Skill.COOKING),
RAW_DARK_CRAB(ItemID.RAW_DARK_CRAB, "Fish", Skill.COOKING),
RAW_MANTA_RAY(ItemID.RAW_MANTA_RAY, "Fish", Skill.COOKING),
GRAPES(ItemID.GRAPES, "Other", Skill.COOKING),
/**
* Crafting Items
*/
WOOL(ItemID.WOOL, "Misc", Skill.CRAFTING),
FLAX(ItemID.FLAX, "Misc", Skill.CRAFTING),
MOLTEN_GLASS(ItemID.MOLTEN_GLASS, "Misc", Skill.CRAFTING),
BATTLESTAFF(ItemID.BATTLESTAFF, "Misc", Skill.CRAFTING),
// D'hide/Dragon Leather
GREEN_DRAGONHIDE(ItemID.GREEN_DRAGONHIDE, "D'hide", Skill.CRAFTING, ItemID.GREEN_DRAGON_LEATHER),
GREEN_DRAGON_LEATHER(ItemID.GREEN_DRAGON_LEATHER, "D'hide", Skill.CRAFTING),
BLUE_DRAGONHIDE(ItemID.BLUE_DRAGONHIDE, "D'hide", Skill.CRAFTING, ItemID.BLUE_DRAGON_LEATHER),
BLUE_DRAGON_LEATHER(ItemID.BLUE_DRAGON_LEATHER, "D'hide", Skill.CRAFTING),
RED_DRAGONHIDE(ItemID.RED_DRAGONHIDE, "D'hide", Skill.CRAFTING, ItemID.RED_DRAGON_LEATHER),
RED_DRAGON_LEATHER(ItemID.RED_DRAGON_LEATHER, "D'hide", Skill.CRAFTING),
BLACK_DRAGONHIDE(ItemID.BLACK_DRAGONHIDE, "D'hide", Skill.CRAFTING, ItemID.BLACK_DRAGON_LEATHER),
BLACK_DRAGON_LEATHER(ItemID.BLACK_DRAGON_LEATHER, "D'hide", Skill.CRAFTING),
// Uncut Gems
UNCUT_OPAL(ItemID.UNCUT_OPAL, "Gems", Skill.CRAFTING, ItemID.OPAL),
UNCUT_JADE(ItemID.UNCUT_JADE, "Gems", Skill.CRAFTING, ItemID.JADE),
UNCUT_RED_TOPAZ(ItemID.UNCUT_RED_TOPAZ, "Gems", Skill.CRAFTING, ItemID.RED_TOPAZ),
UNCUT_SAPPHIRE(ItemID.UNCUT_SAPPHIRE, "Gems", Skill.CRAFTING, ItemID.SAPPHIRE),
UNCUT_EMERALD(ItemID.UNCUT_EMERALD, "Gems", Skill.CRAFTING, ItemID.EMERALD),
UNCUT_RUBY(ItemID.UNCUT_RUBY, "Gems", Skill.CRAFTING, ItemID.RUBY),
UNCUT_DIAMOND(ItemID.UNCUT_DIAMOND, "Gems", Skill.CRAFTING, ItemID.DIAMOND),
UNCUT_DRAGONSTONE(ItemID.UNCUT_DRAGONSTONE, "Gems", Skill.CRAFTING, ItemID.DRAGONSTONE),
UNCUT_ONYX(ItemID.UNCUT_ONYX, "Gems", Skill.CRAFTING, ItemID.ONYX),
UNCUT_ZENYTE(ItemID.UNCUT_ZENYTE, "Gems", Skill.CRAFTING, ItemID.ZENYTE),
// Cut Gems
OPAL(ItemID.OPAL, "Gems", Skill.CRAFTING),
JADE(ItemID.JADE, "Gems", Skill.CRAFTING),
RED_TOPAZ(ItemID.RED_TOPAZ, "Gems", Skill.CRAFTING),
SAPPHIRE(ItemID.SAPPHIRE, "Gems", Skill.CRAFTING),
EMERALD(ItemID.EMERALD, "Gems", Skill.CRAFTING),
RUBY(ItemID.RUBY, "Gems", Skill.CRAFTING),
DIAMOND(ItemID.DIAMOND, "Gems", Skill.CRAFTING),
DRAGONSTONE(ItemID.DRAGONSTONE, "Gems", Skill.CRAFTING),
ONYX(ItemID.ONYX, "Gems", Skill.CRAFTING),
ZENYTE(ItemID.ZENYTE, "Gems", Skill.CRAFTING),
/**
* Smithing Items
*/
// Ores
IRON_ORE(ItemID.IRON_ORE, "Ore", Skill.SMITHING),
SILVER_ORE(ItemID.SILVER_ORE, "Ore", Skill.SMITHING),
GOLD_ORE(ItemID.GOLD_ORE, "Ore", Skill.SMITHING),
MITHRIL_ORE(ItemID.MITHRIL_ORE, "Ore", Skill.SMITHING),
ADAMANTITE_ORE(ItemID.ADAMANTITE_ORE, "Ore", Skill.SMITHING),
RUNITE_ORE(ItemID.RUNITE_ORE, "Ore", Skill.SMITHING),
// Bars
BRONZE_BAR(ItemID.BRONZE_BAR, "Bars", Skill.SMITHING),
IRON_BAR(ItemID.IRON_BAR, "Bars", Skill.SMITHING),
STEEL_BAR(ItemID.STEEL_BAR, "Bars", Skill.SMITHING),
MITHRIL_BAR(ItemID.MITHRIL_BAR, "Bars", Skill.SMITHING),
ADAMANTITE_BAR(ItemID.ADAMANTITE_BAR, "Bars", Skill.SMITHING),
RUNITE_BAR(ItemID.RUNITE_BAR, "Bars", Skill.SMITHING),
/**
* Farming Items
*/
// Seeds
ACORN(ItemID.ACORN, "Seeds", Skill.FARMING),
WILLOW_SEED(ItemID.WILLOW_SEED, "Seeds", Skill.FARMING),
MAPLE_SEED(ItemID.MAPLE_SEED, "Seeds", Skill.FARMING),
YEW_SEED(ItemID.YEW_SEED, "Seeds", Skill.FARMING),
MAGIC_SEED(ItemID.MAGIC_SEED, "Seeds", Skill.FARMING),
APPLE_TREE_SEED(ItemID.APPLE_TREE_SEED, "Seeds", Skill.FARMING),
BANANA_TREE_SEED(ItemID.BANANA_TREE_SEED, "Seeds", Skill.FARMING),
ORANGE_TREE_SEED(ItemID.ORANGE_TREE_SEED, "Seeds", Skill.FARMING),
CURRY_TREE_SEED(ItemID.CURRY_TREE_SEED, "Seeds", Skill.FARMING),
PINEAPPLE_SEED(ItemID.PINEAPPLE_SEED, "Seeds", Skill.FARMING),
PAPAYA_TREE_SEED(ItemID.PAPAYA_TREE_SEED, "Seeds", Skill.FARMING),
PALM_TREE_SEED(ItemID.PALM_TREE_SEED, "Seeds", Skill.FARMING),
CALQUAT_TREE_SEED(ItemID.CALQUAT_TREE_SEED, "Seeds", Skill.FARMING),
TEAK_SEED(ItemID.TEAK_SEED, "Seeds", Skill.FARMING),
MAHOGANY_SEED(ItemID.MAHOGANY_SEED, "Seeds", Skill.FARMING),
SPIRIT_SEED(ItemID.SPIRIT_SEED, "Seeds", Skill.FARMING),
// Saplings
OAK_SAPLING(ItemID.OAK_SAPLING, "Saplings", Skill.FARMING, ItemID.ACORN),
WILLOW_SAPLING(ItemID.WILLOW_SAPLING, "Saplings", Skill.FARMING, ItemID.WILLOW_SEED),
MAPLE_SAPLING(ItemID.MAPLE_SAPLING, "Saplings", Skill.FARMING, ItemID.MAPLE_SEED),
YEW_SAPLING(ItemID.YEW_SAPLING, "Saplings", Skill.FARMING, ItemID.YEW_SEED),
MAGIC_SAPLING(ItemID.MAGIC_SAPLING, "Saplings", Skill.FARMING, ItemID.MAGIC_SEED),
APPLE_TREE_SAPLING(ItemID.APPLE_SAPLING, "Saplings", Skill.FARMING, ItemID.APPLE_TREE_SEED),
BANANA_TREE_SAPLING(ItemID.BANANA_SAPLING, "Saplings", Skill.FARMING, ItemID.BANANA_TREE_SEED),
ORANGE_TREE_SAPLING(ItemID.ORANGE_SAPLING, "Saplings", Skill.FARMING, ItemID.ORANGE_TREE_SEED),
CURRY_TREE_SAPLING(ItemID.CURRY_SAPLING, "Saplings", Skill.FARMING, ItemID.CURRY_TREE_SEED),
PINEAPPLE_SAPLING(ItemID.PINEAPPLE_SAPLING, "Saplings", Skill.FARMING, ItemID.PINEAPPLE_SEED),
PAPAYA_TREE_SAPLING(ItemID.PAPAYA_SAPLING, "Saplings", Skill.FARMING, ItemID.PAPAYA_TREE_SEED),
PALM_TREE_SAPLING(ItemID.PALM_SAPLING, "Saplings", Skill.FARMING, ItemID.PALM_TREE_SEED),
CALQUAT_TREE_SAPLING(ItemID.CALQUAT_SAPLING, "Saplings", Skill.FARMING, ItemID.CALQUAT_TREE_SEED),
TEAK_SAPLING(ItemID.TEAK_SAPLING, "Saplings", Skill.FARMING, ItemID.TEAK_SEED),
MAHOGANY_SAPLING(ItemID.MAHOGANY_SAPLING, "Saplings", Skill.FARMING, ItemID.MAHOGANY_SEED),
SPIRIT_SAPLING(ItemID.SPIRIT_SAPLING, "Saplings", Skill.FARMING, ItemID.SPIRIT_SEED),
;
@Getter
private final int itemID;
@Getter
private final String category;
@Getter
private final Skill skill;
/**
* Should be operated on and then treated like this item or does nothing if null.
* Used mostly for things like herblore where you want Grimy, Clean, and UNF to count for creating potions.
* To do this GRIMY links to CLEAN which links to UNFINISHED which links to null
*/
@Getter
private final int linkedItemId;
@Getter
private boolean ignoreBonus;
@Getter
private ItemDefinition definition;
CriticalItem(int itemID, String category, Skill skill, int linkedItem)
{
this.itemID = itemID;
this.category = category;
this.skill = skill;
this.linkedItemId = linkedItem;
this.definition = null;
this.ignoreBonus = false;
}
CriticalItem(int itemID, String category, Skill skill)
{
this(itemID, category, skill, -1);
}
CriticalItem(int itemID, String category, Skill skill, boolean ignoreBonusXp)
{
this(itemID, category, skill, -1);
this.ignoreBonus = ignoreBonusXp;
}
// Builds a Map to reduce looping frequency
private static Map<Skill, List<CriticalItem>> buildSkillItemMap()
{
Map<Skill, List<CriticalItem>> map = new HashMap<>();
for (CriticalItem item : values())
{
map.computeIfAbsent(item.getSkill(), e -> new ArrayList<>()).add(item);
}
return map;
}
private static final Map<Skill, List<CriticalItem>> bySkillName = buildSkillItemMap();
public static List<CriticalItem> getBySkillName(Skill skill)
{
return bySkillName.get(skill);
}
// Builds a Map to reduce looping frequency
private static Map<Skill, Set<String>> buildSkillCategoryMap()
{
Map<Skill, Set<String>> map = new HashMap<>();
for (CriticalItem item : values())
{
map.computeIfAbsent(item.getSkill(), k -> new HashSet<>()).add(item.category);
}
return map;
}
private static final Map<Skill, Set<String>> bySkillCategory = buildSkillCategoryMap();
public static Set<String> getSkillCategories(Skill skill)
{
return bySkillCategory.get(skill);
}
// Builds a Map to reduce looping frequency
private static Map<String, List<CriticalItem>> buildItemSkillCategoryMap()
{
Map<String, List<CriticalItem>> map = new HashMap<>();
for (CriticalItem item : values())
{
String key = item.getCategory() + item.skill.getName();
map.computeIfAbsent(key, e -> new ArrayList<>()).add(item);
}
return map;
}
private static final Map<String, List<CriticalItem>> itemsBySkillCategory = buildItemSkillCategoryMap();
public static List<CriticalItem> getItemsForSkillCategories(Skill skill, String category)
{
return itemsBySkillCategory.get(category + skill.getName());
}
// Builds a Map to reduce looping frequency
private static Map<Integer, CriticalItem> buildItemsByIdMap()
{
Map<Integer, CriticalItem> map = new HashMap<>();
for (CriticalItem item : values())
{
map.put(item.getItemID(), item);
}
return map;
}
private static final Map<Integer, CriticalItem> itemsById = buildItemsByIdMap();
public static CriticalItem getByItemId(int id)
{
return itemsById.get(id);
}
/**
* Attaches the Item Composition to each Critical Item on client initial load
*
* @param m ItemManager
*/
public static void prepareItemDefinitions(ItemManager m)
{
for (CriticalItem i : values())
{
i.definition = m.getItemDefinition(i.getItemID());
}
}
@Override
public String toString()
{
return "CriticalItem=(name=" + this.name() + ",id=" + this.itemID + ",category=" + this.category + ")";
}
}

View File

@@ -24,17 +24,19 @@
*/
package net.runelite.client.plugins.skillcalculator.banked.beans;
import com.google.common.collect.ImmutableMultimap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import lombok.AccessLevel;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import lombok.Getter;
import net.runelite.api.ItemDefinition;
import net.runelite.api.ItemID;
import net.runelite.api.Skill;
import net.runelite.client.plugins.skillcalculator.banked.CriticalItem;
import net.runelite.client.game.ItemManager;
@Getter(AccessLevel.PUBLIC)
@Getter
public enum Activity
{
/**
@@ -42,372 +44,679 @@ public enum Activity
*/
// Creating Potions
// Guam
GUAM_POTION_UNF(ItemID.GUAM_POTION_UNF, "Unfinished Potion", Skill.HERBLORE, 1, 0, CriticalItem.GUAM_LEAF, ActivitySecondaries.UNFINISHED_POTION),
GUAM_TAR(ItemID.GUAM_TAR, "Guam tar", Skill.HERBLORE, 19, 30, CriticalItem.GUAM_LEAF, ActivitySecondaries.SWAMP_TAR, true),
GUAM_POTION_UNF(ItemID.GUAM_POTION_UNF, "Unfinished Potion", Skill.HERBLORE, 1, 0,
CriticalItem.GUAM_LEAF, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.GUAM_POTION_UNF, 1)),
GUAM_TAR(ItemID.GUAM_TAR, "Guam tar", Skill.HERBLORE, 19, 30,
CriticalItem.GUAM_LEAF, Secondaries.SWAMP_TAR, new ItemStack(ItemID.GUAM_TAR, 15)),
ATTACK_POTION(ItemID.ATTACK_POTION4, "Attack Potion", Skill.HERBLORE, 3, 25, CriticalItem.GUAM_LEAF_POTION_UNF, ActivitySecondaries.ATTACK_POTION),
ATTACK_POTION(ItemID.ATTACK_POTION3, "Attack potion", Skill.HERBLORE, 3, 25,
CriticalItem.GUAM_LEAF_POTION_UNF, Secondaries.ATTACK_POTION, new ItemStack(ItemID.ATTACK_POTION3, 1)),
// Marrentil
MARRENTILL_POTION_UNF(ItemID.MARRENTILL_POTION_UNF, "Unfinished Potion", Skill.HERBLORE, 1, 0, CriticalItem.MARRENTILL, ActivitySecondaries.UNFINISHED_POTION),
MARRENTILL_TAR(ItemID.MARRENTILL_TAR, "Marrentill tar", Skill.HERBLORE, 31, 42.5, CriticalItem.MARRENTILL, ActivitySecondaries.SWAMP_TAR, true),
MARRENTILL_POTION_UNF(ItemID.MARRENTILL_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 1, 0,
CriticalItem.MARRENTILL, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.MARRENTILL_POTION_UNF, 1)),
MARRENTILL_TAR(ItemID.MARRENTILL_TAR, "Marrentill tar", Skill.HERBLORE, 31, 42.5,
CriticalItem.MARRENTILL, Secondaries.SWAMP_TAR, new ItemStack(ItemID.MARRENTILL_TAR, 15)),
ANTIPOISON(ItemID.ANTIPOISON4, "Antipoison", Skill.HERBLORE, 5, 37.5, CriticalItem.MARRENTILL_POTION_UNF, ActivitySecondaries.ANTIPOISON),
ANTIPOISON(ItemID.ANTIPOISON3, "Antipoison", Skill.HERBLORE, 5, 37.5,
CriticalItem.MARRENTILL_POTION_UNF, Secondaries.ANTIPOISON, new ItemStack(ItemID.ANTIPOISON3, 1)),
// Tarromin
TARROMIN_POTION_UNF(ItemID.TARROMIN_POTION_UNF, "Unfinished Potion", Skill.HERBLORE, 1, 0, CriticalItem.TARROMIN, ActivitySecondaries.UNFINISHED_POTION),
TARROMIN_TAR(ItemID.TARROMIN_TAR, "Tarromin tar", Skill.HERBLORE, 39, 55, CriticalItem.TARROMIN, ActivitySecondaries.SWAMP_TAR, true),
TARROMIN_POTION_UNF(ItemID.TARROMIN_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 1, 0,
CriticalItem.TARROMIN, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.TARROMIN_POTION_UNF, 1)),
TARROMIN_TAR(ItemID.TARROMIN_TAR, "Tarromin tar", Skill.HERBLORE, 39, 55,
CriticalItem.TARROMIN, Secondaries.SWAMP_TAR, new ItemStack(ItemID.TARROMIN_TAR, 15)),
STRENGTH_POTION(ItemID.STRENGTH_POTION4, "Strength potion", Skill.HERBLORE, 12, 50, CriticalItem.TARROMIN_POTION_UNF, ActivitySecondaries.STRENGTH_POTION),
SERUM_207(ItemID.SERUM_207_4, "Serum 207", Skill.HERBLORE, 15, 50, CriticalItem.TARROMIN_POTION_UNF, ActivitySecondaries.SERUM_207),
STRENGTH_POTION(ItemID.STRENGTH_POTION3, "Strength potion", Skill.HERBLORE, 12, 50,
CriticalItem.TARROMIN_POTION_UNF, Secondaries.STRENGTH_POTION, new ItemStack(ItemID.STRENGTH_POTION3, 1)),
SERUM_207(ItemID.SERUM_207_3, "Serum 207", Skill.HERBLORE, 15, 50,
CriticalItem.TARROMIN_POTION_UNF, Secondaries.SERUM_207, new ItemStack(ItemID.SERUM_207_3, 1)),
// Harralander
HARRALANDER_POTION_UNF(ItemID.HARRALANDER_POTION_UNF, "Unfinished Potion", Skill.HERBLORE, 1, 0, CriticalItem.HARRALANDER, ActivitySecondaries.UNFINISHED_POTION),
HARRALANDER_TAR(ItemID.HARRALANDER_TAR, "Harralander tar", Skill.HERBLORE, 44, 72.5, CriticalItem.HARRALANDER, ActivitySecondaries.SWAMP_TAR, true),
HARRALANDER_POTION_UNF(ItemID.HARRALANDER_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 1, 0,
CriticalItem.HARRALANDER, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.HARRALANDER_POTION_UNF, 1)),
HARRALANDER_TAR(ItemID.HARRALANDER_TAR, "Harralander tar", Skill.HERBLORE, 44, 72.5,
CriticalItem.HARRALANDER, Secondaries.SWAMP_TAR, new ItemStack(ItemID.HARRALANDER_TAR, 15)),
COMPOST_POTION(ItemID.COMPOST_POTION4, "Compost potion", Skill.HERBLORE, 21, 60, CriticalItem.HARRALANDER_POTION_UNF, ActivitySecondaries.COMPOST_POTION),
RESTORE_POTION(ItemID.RESTORE_POTION4, "Restore potion", Skill.HERBLORE, 22, 62.5, CriticalItem.HARRALANDER_POTION_UNF, ActivitySecondaries.RESTORE_POTION),
ENERGY_POTION(ItemID.ENERGY_POTION4, "Energy potion", Skill.HERBLORE, 26, 67.5, CriticalItem.HARRALANDER_POTION_UNF, ActivitySecondaries.ENERGY_POTION),
COMBAT_POTION(ItemID.COMBAT_POTION4, "Combat potion", Skill.HERBLORE, 36, 84, CriticalItem.HARRALANDER_POTION_UNF, ActivitySecondaries.COMBAT_POTION),
COMPOST_POTION(ItemID.COMPOST_POTION3, "Compost potion", Skill.HERBLORE, 21, 60,
CriticalItem.HARRALANDER_POTION_UNF, Secondaries.COMPOST_POTION, new ItemStack(ItemID.COMPOST_POTION3, 1)),
RESTORE_POTION(ItemID.RESTORE_POTION3, "Restore potion", Skill.HERBLORE, 22, 62.5,
CriticalItem.HARRALANDER_POTION_UNF, Secondaries.RESTORE_POTION, new ItemStack(ItemID.RESTORE_POTION3, 1)),
ENERGY_POTION(ItemID.ENERGY_POTION3, "Energy potion", Skill.HERBLORE, 26, 67.5,
CriticalItem.HARRALANDER_POTION_UNF, Secondaries.ENERGY_POTION, new ItemStack(ItemID.ENERGY_POTION3, 1)),
COMBAT_POTION(ItemID.COMBAT_POTION3, "Combat potion", Skill.HERBLORE, 36, 84,
CriticalItem.HARRALANDER_POTION_UNF, Secondaries.COMBAT_POTION, new ItemStack(ItemID.COMBAT_POTION3, 1)),
// Ranarr Weed
DEFENCE_POTION(ItemID.DEFENCE_POTION4, "Defence potion", Skill.HERBLORE, 30, 75, CriticalItem.RANARR_POTION_UNF, ActivitySecondaries.DEFENCE_POTION),
PRAYER_POTION(ItemID.PRAYER_POTION4, "Prayer potion", Skill.HERBLORE, 38, 87.5, CriticalItem.RANARR_POTION_UNF, ActivitySecondaries.PRAYER_POTION),
RANARR_POTION_UNF(ItemID.RANARR_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 30, 0,
CriticalItem.RANARR_WEED, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.RANARR_POTION_UNF, 1)),
DEFENCE_POTION(ItemID.DEFENCE_POTION3, "Defence potion", Skill.HERBLORE, 30, 75,
CriticalItem.RANARR_POTION_UNF, Secondaries.DEFENCE_POTION, new ItemStack(ItemID.DEFENCE_POTION3, 1)),
PRAYER_POTION(ItemID.PRAYER_POTION3, "Prayer potion", Skill.HERBLORE, 38, 87.5,
CriticalItem.RANARR_POTION_UNF, Secondaries.PRAYER_POTION, new ItemStack(ItemID.PRAYER_POTION3, 1)),
// Toadflax
AGILITY_POTION(ItemID.AGILITY_POTION4, "Agility potion", Skill.HERBLORE, 34, 80, CriticalItem.TOADFLAX_POTION_UNF, ActivitySecondaries.AGILITY_POTION),
SARADOMIN_BREW(ItemID.SARADOMIN_BREW4, "Saradomin brew", Skill.HERBLORE, 81, 180, CriticalItem.TOADFLAX_POTION_UNF, ActivitySecondaries.SARADOMIN_BREW),
TOADFLAX_POTION_UNF(ItemID.TOADFLAX_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 34, 0,
CriticalItem.TOADFLAX, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.TOADFLAX_POTION_UNF, 1)),
AGILITY_POTION(ItemID.AGILITY_POTION3, "Agility potion", Skill.HERBLORE, 34, 80,
CriticalItem.TOADFLAX_POTION_UNF, Secondaries.AGILITY_POTION, new ItemStack(ItemID.AGILITY_POTION3, 1)),
SARADOMIN_BREW(ItemID.SARADOMIN_BREW3, "Saradomin brew", Skill.HERBLORE, 81, 180,
CriticalItem.TOADFLAX_POTION_UNF, Secondaries.SARADOMIN_BREW, new ItemStack(ItemID.SARADOMIN_BREW3, 1)),
// Irit
SUPER_ATTACK(ItemID.SUPER_ATTACK4, "Super attack", Skill.HERBLORE, 45, 100, CriticalItem.IRIT_POTION_UNF, ActivitySecondaries.SUPER_ATTACK),
SUPERANTIPOISON(ItemID.SUPERANTIPOISON4, "Superantipoison", Skill.HERBLORE, 48, 106.3, CriticalItem.IRIT_POTION_UNF, ActivitySecondaries.SUPERANTIPOISON),
IRIT_POTION_UNF(ItemID.IRIT_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 45, 0,
CriticalItem.IRIT_LEAF, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.IRIT_POTION_UNF, 1)),
SUPER_ATTACK(ItemID.SUPER_ATTACK3, "Super attack", Skill.HERBLORE, 45, 100,
CriticalItem.IRIT_POTION_UNF, Secondaries.SUPER_ATTACK, new ItemStack(ItemID.SUPER_ATTACK3, 1)),
SUPERANTIPOISON(ItemID.SUPERANTIPOISON3, "Superantipoison", Skill.HERBLORE, 48, 106.3,
CriticalItem.IRIT_POTION_UNF, Secondaries.SUPERANTIPOISON, new ItemStack(ItemID.SUPERANTIPOISON3, 1)),
// Avantoe
FISHING_POTION(ItemID.FISHING_POTION4, "Fishing potion", Skill.HERBLORE, 50, 112.5, CriticalItem.AVANTOE_POTION_UNF, ActivitySecondaries.FISHING_POTION),
SUPER_ENERGY_POTION(ItemID.SUPER_ENERGY3_20549, "Super energy potion", Skill.HERBLORE, 52, 117.5, CriticalItem.AVANTOE_POTION_UNF, ActivitySecondaries.SUPER_ENERGY_POTION),
HUNTER_POTION(ItemID.HUNTER_POTION4, "Hunter potion", Skill.HERBLORE, 53, 120, CriticalItem.AVANTOE_POTION_UNF, ActivitySecondaries.HUNTER_POTION),
AVANTOE_POTION_UNF(ItemID.AVANTOE_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 50, 0,
CriticalItem.AVANTOE, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.AVANTOE_POTION_UNF, 1)),
FISHING_POTION(ItemID.FISHING_POTION3, "Fishing potion", Skill.HERBLORE, 50, 112.5,
CriticalItem.AVANTOE_POTION_UNF, Secondaries.FISHING_POTION, new ItemStack(ItemID.FISHING_POTION3, 1)),
SUPER_ENERGY_POTION(ItemID.SUPER_ENERGY3_20549, "Super energy potion", Skill.HERBLORE, 52, 117.5,
CriticalItem.AVANTOE_POTION_UNF, Secondaries.SUPER_ENERGY_POTION, new ItemStack(ItemID.SUPER_ENERGY3_20549, 1)),
HUNTER_POTION(ItemID.HUNTER_POTION3, "Hunter potion", Skill.HERBLORE, 53, 120,
CriticalItem.AVANTOE_POTION_UNF, Secondaries.HUNTER_POTION, new ItemStack(ItemID.HUNTER_POTION3, 1)),
// Kwuarm
SUPER_STRENGTH(ItemID.SUPER_STRENGTH4, "Super strength", Skill.HERBLORE, 55, 125, CriticalItem.KWUARM_POTION_UNF, ActivitySecondaries.SUPER_STRENGTH),
KWUARM_POTION_UNF(ItemID.KWUARM_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 55, 0,
CriticalItem.KWUARM, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.KWUARM_POTION_UNF, 1)),
SUPER_STRENGTH(ItemID.SUPER_STRENGTH3, "Super strength", Skill.HERBLORE, 55, 125,
CriticalItem.KWUARM_POTION_UNF, Secondaries.SUPER_STRENGTH, new ItemStack(ItemID.SUPER_STRENGTH3, 1)),
// Snapdragon
SUPER_RESTORE(ItemID.SUPER_RESTORE4, "Super restore", Skill.HERBLORE, 63, 142.5, CriticalItem.SNAPDRAGON_POTION_UNF, ActivitySecondaries.SUPER_RESTORE),
SANFEW_SERUM(ItemID.SANFEW_SERUM4, "Sanfew serum", Skill.HERBLORE, 65, 160, CriticalItem.SNAPDRAGON_POTION_UNF, ActivitySecondaries.SANFEW_SERUM),
SNAPDRAGON_POTION_UNF(ItemID.SNAPDRAGON_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 63, 0,
CriticalItem.SNAPDRAGON, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.SNAPDRAGON_POTION_UNF, 1)),
SUPER_RESTORE(ItemID.SUPER_RESTORE3, "Super restore", Skill.HERBLORE, 63, 142.5,
CriticalItem.SNAPDRAGON_POTION_UNF, Secondaries.SUPER_RESTORE, new ItemStack(ItemID.SUPER_RESTORE3, 1)),
SANFEW_SERUM(ItemID.SANFEW_SERUM3, "Sanfew serum", Skill.HERBLORE, 65, 160,
CriticalItem.SNAPDRAGON_POTION_UNF, Secondaries.SANFEW_SERUM, new ItemStack(ItemID.SANFEW_SERUM3, 1)),
// Cadantine
SUPER_DEFENCE_POTION(ItemID.SUPER_DEFENCE4, "Super defence", Skill.HERBLORE, 66, 150, CriticalItem.CADANTINE_POTION_UNF, ActivitySecondaries.SUPER_DEFENCE_POTION),
CADANTINE_POTION_UNF(ItemID.CADANTINE_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 66, 0,
CriticalItem.CADANTINE, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.CADANTINE_POTION_UNF, 1)),
SUPER_DEFENCE_POTION(ItemID.SUPER_DEFENCE3, "Super defence", Skill.HERBLORE, 66, 150,
CriticalItem.CADANTINE_POTION_UNF, Secondaries.SUPER_DEFENCE_POTION, new ItemStack(ItemID.SUPER_DEFENCE3, 1)),
// Lantadyme
ANTIFIRE_POTION(ItemID.ANTIFIRE_POTION4, "Anti-fire potion", Skill.HERBLORE, 69, 157.5, CriticalItem.LANTADYME_POTION_UNF, ActivitySecondaries.ANTIFIRE_POTION),
MAGIC_POTION(ItemID.MAGIC_POTION4, "Magic potion", Skill.HERBLORE, 76, 172.5, CriticalItem.LANTADYME_POTION_UNF, ActivitySecondaries.MAGIC_POTION),
LANTADYME_POTION_UNF(ItemID.LANTADYME_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 69, 0,
CriticalItem.LANTADYME, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.LANTADYME_POTION_UNF, 1)),
ANTIFIRE_POTION(ItemID.ANTIFIRE_POTION3, "Anti-fire potion", Skill.HERBLORE, 69, 157.5,
CriticalItem.LANTADYME_POTION_UNF, Secondaries.ANTIFIRE_POTION, new ItemStack(ItemID.ANTIFIRE_POTION3, 1)),
MAGIC_POTION(ItemID.MAGIC_POTION3, "Magic potion", Skill.HERBLORE, 76, 172.5,
CriticalItem.LANTADYME_POTION_UNF, Secondaries.MAGIC_POTION, new ItemStack(ItemID.MAGIC_POTION3, 1)),
// Dwarf Weed
RANGING_POTION(ItemID.RANGING_POTION4, "Ranging potion", Skill.HERBLORE, 72, 162.5, CriticalItem.DWARF_WEED_POTION_UNF, ActivitySecondaries.RANGING_POTION),
DWARF_WEED_POTION_UNF(ItemID.DWARF_WEED_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 72, 0,
CriticalItem.DWARF_WEED, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.DWARF_WEED_POTION_UNF, 1)),
RANGING_POTION(ItemID.RANGING_POTION3, "Ranging potion", Skill.HERBLORE, 72, 162.5,
CriticalItem.DWARF_WEED_POTION_UNF, Secondaries.RANGING_POTION, new ItemStack(ItemID.RANGING_POTION3, 1)),
// Torstol
TORSTOL_POTION_UNF(ItemID.TORSTOL_POTION_UNF, "Unfinished Potion", Skill.HERBLORE, 78, 0, CriticalItem.TORSTOL, ActivitySecondaries.UNFINISHED_POTION),
SUPER_COMBAT_POTION(ItemID.SUPER_COMBAT_POTION4, "Super combat", Skill.HERBLORE, 90, 150, CriticalItem.TORSTOL, ActivitySecondaries.SUPER_COMBAT_POTION, true),
ANTIVENOM_PLUS(ItemID.ANTIVENOM4_12913, "Anti-venom+", Skill.HERBLORE, 94, 125, CriticalItem.TORSTOL, ActivitySecondaries.ANTIVENOM_PLUS, true),
TORSTOL_POTION_UNF(ItemID.TORSTOL_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 78, 0,
CriticalItem.TORSTOL, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.TORSTOL_POTION_UNF, 1)),
SUPER_COMBAT_POTION(ItemID.SUPER_COMBAT_POTION4, "Super combat", Skill.HERBLORE, 90, 150,
CriticalItem.TORSTOL, Secondaries.SUPER_COMBAT_POTION, new ItemStack(ItemID.SUPER_COMBAT_POTION4, 1)),
ANTIVENOM_PLUS(ItemID.ANTIVENOM3_12915, "Anti-venom+", Skill.HERBLORE, 94, 125,
CriticalItem.TORSTOL, Secondaries.ANTIVENOM_PLUS, new ItemStack(ItemID.ANTIVENOM3_12915, 1)),
ZAMORAK_BREW(ItemID.ZAMORAK_BREW4, "Zamorak brew", Skill.HERBLORE, 78, 175, CriticalItem.TORSTOL_POTION_UNF, ActivitySecondaries.ZAMORAK_BREW),
ZAMORAK_BREW(ItemID.ZAMORAK_BREW3, "Zamorak brew", Skill.HERBLORE, 78, 175,
CriticalItem.TORSTOL_POTION_UNF, Secondaries.ZAMORAK_BREW, new ItemStack(ItemID.ZAMORAK_BREW3, 1)),
// Cleaning Grimy Herbs
CLEAN_GUAM(ItemID.GUAM_LEAF, "Clean guam", Skill.HERBLORE, 3, 2.5, CriticalItem.GRIMY_GUAM_LEAF),
CLEAN_MARRENTILL(ItemID.MARRENTILL, "Clean marrentill", Skill.HERBLORE, 5, 3.8, CriticalItem.GRIMY_MARRENTILL),
CLEAN_TARROMIN(ItemID.TARROMIN, "Clean tarromin", Skill.HERBLORE, 11, 5, CriticalItem.GRIMY_TARROMIN),
CLEAN_HARRALANDER(ItemID.HARRALANDER, "Clean harralander", Skill.HERBLORE, 20, 6.3, CriticalItem.GRIMY_HARRALANDER),
CLEAN_RANARR_WEED(ItemID.RANARR_WEED, "Clean ranarr weed", Skill.HERBLORE, 25, 7.5, CriticalItem.GRIMY_RANARR_WEED),
CLEAN_TOADFLAX(ItemID.TOADFLAX, "Clean toadflax", Skill.HERBLORE, 30, 8, CriticalItem.GRIMY_TOADFLAX),
CLEAN_IRIT_LEAF(ItemID.IRIT_LEAF, "Clean irit leaf", Skill.HERBLORE, 40, 8.8, CriticalItem.GRIMY_IRIT_LEAF),
CLEAN_AVANTOE(ItemID.AVANTOE, "Clean avantoe", Skill.HERBLORE, 48, 10, CriticalItem.GRIMY_AVANTOE),
CLEAN_KWUARM(ItemID.KWUARM, "Clean kwuarm", Skill.HERBLORE, 54, 11.3, CriticalItem.GRIMY_KWUARM),
CLEAN_SNAPDRAGON(ItemID.SNAPDRAGON, "Clean snapdragon", Skill.HERBLORE, 59, 11.8, CriticalItem.GRIMY_SNAPDRAGON),
CLEAN_CADANTINE(ItemID.CADANTINE, "Clean cadantine", Skill.HERBLORE, 65, 12.5, CriticalItem.GRIMY_CADANTINE),
CLEAN_LANTADYME(ItemID.LANTADYME, "Clean lantadyme", Skill.HERBLORE, 67, 13.1, CriticalItem.GRIMY_LANTADYME),
CLEAN_DWARF_WEED(ItemID.DWARF_WEED, "Clean dwarf weed", Skill.HERBLORE, 70, 13.8, CriticalItem.GRIMY_DWARF_WEED),
CLEAN_TORSTOL(ItemID.TORSTOL, "Clean torstol", Skill.HERBLORE, 75, 15, CriticalItem.GRIMY_TORSTOL),
CLEAN_GUAM(ItemID.GUAM_LEAF, "Clean guam", Skill.HERBLORE, 3, 2.5,
CriticalItem.GRIMY_GUAM_LEAF, null, new ItemStack(ItemID.GUAM_LEAF, 1)),
CLEAN_MARRENTILL(ItemID.MARRENTILL, "Clean marrentill", Skill.HERBLORE, 5, 3.8,
CriticalItem.GRIMY_MARRENTILL, null, new ItemStack(ItemID.MARRENTILL, 1)),
CLEAN_TARROMIN(ItemID.TARROMIN, "Clean tarromin", Skill.HERBLORE, 11, 5,
CriticalItem.GRIMY_TARROMIN, null, new ItemStack(ItemID.TARROMIN, 1)),
CLEAN_HARRALANDER(ItemID.HARRALANDER, "Clean harralander", Skill.HERBLORE, 20, 6.3,
CriticalItem.GRIMY_HARRALANDER, null, new ItemStack(ItemID.HARRALANDER, 1)),
CLEAN_RANARR_WEED(ItemID.RANARR_WEED, "Clean ranarr weed", Skill.HERBLORE, 25, 7.5,
CriticalItem.GRIMY_RANARR_WEED, null, new ItemStack(ItemID.RANARR_WEED, 1)),
CLEAN_TOADFLAX(ItemID.TOADFLAX, "Clean toadflax", Skill.HERBLORE, 30, 8,
CriticalItem.GRIMY_TOADFLAX, null, new ItemStack(ItemID.TOADFLAX, 1)),
CLEAN_IRIT_LEAF(ItemID.IRIT_LEAF, "Clean irit leaf", Skill.HERBLORE, 40, 8.8,
CriticalItem.GRIMY_IRIT_LEAF, null, new ItemStack(ItemID.IRIT_LEAF, 1)),
CLEAN_AVANTOE(ItemID.AVANTOE, "Clean avantoe", Skill.HERBLORE, 48, 10,
CriticalItem.GRIMY_AVANTOE, null, new ItemStack(ItemID.AVANTOE, 1)),
CLEAN_KWUARM(ItemID.KWUARM, "Clean kwuarm", Skill.HERBLORE, 54, 11.3,
CriticalItem.GRIMY_KWUARM, null, new ItemStack(ItemID.KWUARM, 1)),
CLEAN_SNAPDRAGON(ItemID.SNAPDRAGON, "Clean snapdragon", Skill.HERBLORE, 59, 11.8,
CriticalItem.GRIMY_SNAPDRAGON, null, new ItemStack(ItemID.SNAPDRAGON, 1)),
CLEAN_CADANTINE(ItemID.CADANTINE, "Clean cadantine", Skill.HERBLORE, 65, 12.5,
CriticalItem.GRIMY_CADANTINE, null, new ItemStack(ItemID.CADANTINE, 1)),
CLEAN_LANTADYME(ItemID.LANTADYME, "Clean lantadyme", Skill.HERBLORE, 67, 13.1,
CriticalItem.GRIMY_LANTADYME, null, new ItemStack(ItemID.LANTADYME, 1)),
CLEAN_DWARF_WEED(ItemID.DWARF_WEED, "Clean dwarf weed", Skill.HERBLORE, 70, 13.8,
CriticalItem.GRIMY_DWARF_WEED, null, new ItemStack(ItemID.DWARF_WEED, 1)),
CLEAN_TORSTOL(ItemID.TORSTOL, "Clean torstol", Skill.HERBLORE, 75, 15,
CriticalItem.GRIMY_TORSTOL, null, new ItemStack(ItemID.TORSTOL, 1)),
/**
* Construction Options
*/
PLANKS(ItemID.PLANK, "Normal Plank Products", Skill.CONSTRUCTION, 1, 29, CriticalItem.PLANK),
OAK_PLANKS(ItemID.OAK_PLANK, "Normal Oak Products", Skill.CONSTRUCTION, 1, 60, CriticalItem.OAK_PLANK),
TEAK_PLANKS(ItemID.TEAK_PLANK, "Normal Teak Products", Skill.CONSTRUCTION, 1, 90, CriticalItem.TEAK_PLANK),
MYTHICAL_CAPE(ItemID.MYTHICAL_CAPE, "Mythical Cape Rakes", Skill.CONSTRUCTION, 1, 123.33, CriticalItem.TEAK_PLANK),
MAHOGANY_PLANKS(ItemID.MAHOGANY_PLANK, "Normal Mahogany Products", Skill.CONSTRUCTION, 1, 140, CriticalItem.MAHOGANY_PLANK),
PLANK(ItemID.PLANK, "Regular Plank", Skill.CONSTRUCTION, 1, 0,
CriticalItem.LOGS, Secondaries.COINS_100, new ItemStack(ItemID.PLANK, 1)),
PLANKS(ItemID.PLANK, "Regular plank products", Skill.CONSTRUCTION, 1, 29,
CriticalItem.PLANK, null, null),
OAK_PLANK(ItemID.OAK_PLANK, "Oak Plank", Skill.CONSTRUCTION, 1, 0,
CriticalItem.OAK_LOGS, Secondaries.COINS_250, new ItemStack(ItemID.OAK_PLANK, 1)),
OAK_PLANKS(ItemID.OAK_PLANK, "Oak products", Skill.CONSTRUCTION, 1, 60,
CriticalItem.OAK_PLANK, null, null),
TEAK_PLANK(ItemID.TEAK_PLANK, "Teak Plank", Skill.CONSTRUCTION, 1, 0,
CriticalItem.TEAK_LOGS, Secondaries.COINS_500, new ItemStack(ItemID.TEAK_PLANK, 1)),
TEAK_PLANKS(ItemID.TEAK_PLANK, "Teak products", Skill.CONSTRUCTION, 1, 90,
CriticalItem.TEAK_PLANK, null, null),
MYTHICAL_CAPE(ItemID.MYTHICAL_CAPE, "Mythical cape rakes", Skill.CONSTRUCTION, 1, 123.33,
CriticalItem.TEAK_PLANK, null, null),
MAHOGANY_PLANK(ItemID.MAHOGANY_PLANK, "Mahogany Plank", Skill.CONSTRUCTION, 1, 0,
CriticalItem.MAHOGANY_LOGS, Secondaries.COINS_1500, new ItemStack(ItemID.MAHOGANY_PLANK, 1)),
MAHOGANY_PLANKS(ItemID.MAHOGANY_PLANK, "Mahogany products", Skill.CONSTRUCTION, 1, 140,
CriticalItem.MAHOGANY_PLANK, null, null),
/**
* Prayer Options
*/
BONES(ItemID.BONES, "Bones", Skill.PRAYER, 1, 4.5, CriticalItem.BONES),
WOLF_BONES(ItemID.WOLF_BONES, "Bones", Skill.PRAYER, 1, 4.5, CriticalItem.WOLF_BONES),
BURNT_BONES(ItemID.BURNT_BONES, "Bones", Skill.PRAYER, 1, 4.5, CriticalItem.BURNT_BONES),
MONKEY_BONES(ItemID.MONKEY_BONES, "Bones", Skill.PRAYER, 1, 5.0, CriticalItem.MONKEY_BONES),
BAT_BONES(ItemID.BAT_BONES, "Bones", Skill.PRAYER, 1, 5.3, CriticalItem.BAT_BONES),
JOGRE_BONES(ItemID.JOGRE_BONES, "Bones", Skill.PRAYER, 1, 15.0, CriticalItem.JOGRE_BONES),
BIG_BONES(ItemID.BIG_BONES, "Bones", Skill.PRAYER, 1, 15.0, CriticalItem.BIG_BONES),
ZOGRE_BONES(ItemID.ZOGRE_BONES, "Bones", Skill.PRAYER, 1, 22.5, CriticalItem.ZOGRE_BONES),
SHAIKAHAN_BONES(ItemID.SHAIKAHAN_BONES, "Bones", Skill.PRAYER, 1, 25.0, CriticalItem.SHAIKAHAN_BONES),
BABYDRAGON_BONES(ItemID.BABYDRAGON_BONES, "Bones", Skill.PRAYER, 1, 30.0, CriticalItem.BABYDRAGON_BONES),
WYVERN_BONES(ItemID.WYVERN_BONES, "Bones", Skill.PRAYER, 1, 72.0, CriticalItem.WYVERN_BONES),
DRAGON_BONES(ItemID.DRAGON_BONES, "Bones", Skill.PRAYER, 1, 72.0, CriticalItem.DRAGON_BONES),
FAYRG_BONES(ItemID.FAYRG_BONES, "Bones", Skill.PRAYER, 1, 84.0, CriticalItem.FAYRG_BONES),
LAVA_DRAGON_BONES(ItemID.LAVA_DRAGON_BONES, "Bones", Skill.PRAYER, 1, 85.0, CriticalItem.LAVA_DRAGON_BONES),
RAURG_BONES(ItemID.RAURG_BONES, "Bones", Skill.PRAYER, 1, 96.0, CriticalItem.RAURG_BONES),
DAGANNOTH_BONES(ItemID.DAGANNOTH_BONES, "Bones", Skill.PRAYER, 1, 125.0, CriticalItem.DAGANNOTH_BONES),
OURG_BONES(ItemID.OURG_BONES, "Bones", Skill.PRAYER, 1, 140.0, CriticalItem.OURG_BONES),
SUPERIOR_DRAGON_BONES(ItemID.SUPERIOR_DRAGON_BONES, "Bones", Skill.PRAYER, 1, 150.0, CriticalItem.SUPERIOR_DRAGON_BONES),
BONES(ItemID.BONES, "Bones", Skill.PRAYER, 1, 4.5,
CriticalItem.BONES, null, null),
WOLF_BONES(ItemID.WOLF_BONES, "Wolf bones", Skill.PRAYER, 1, 4.5,
CriticalItem.WOLF_BONES, null, null),
BURNT_BONES(ItemID.BURNT_BONES, "Burnt bones", Skill.PRAYER, 1, 4.5,
CriticalItem.BURNT_BONES, null, null),
MONKEY_BONES(ItemID.MONKEY_BONES, "Monkey bones", Skill.PRAYER, 1, 5.0,
CriticalItem.MONKEY_BONES, null, null),
BAT_BONES(ItemID.BAT_BONES, "Bat bones", Skill.PRAYER, 1, 5.3,
CriticalItem.BAT_BONES, null, null),
JOGRE_BONES(ItemID.JOGRE_BONES, "Jogre bones", Skill.PRAYER, 1, 15.0,
CriticalItem.JOGRE_BONES, null, null),
BIG_BONES(ItemID.BIG_BONES, "Big bones", Skill.PRAYER, 1, 15.0,
CriticalItem.BIG_BONES, null, null),
ZOGRE_BONES(ItemID.ZOGRE_BONES, "Zogre bones", Skill.PRAYER, 1, 22.5,
CriticalItem.ZOGRE_BONES, null, null),
SHAIKAHAN_BONES(ItemID.SHAIKAHAN_BONES, "Shaikahan bones", Skill.PRAYER, 1, 25.0,
CriticalItem.SHAIKAHAN_BONES, null, null),
BABYDRAGON_BONES(ItemID.BABYDRAGON_BONES, "Babydragon bones", Skill.PRAYER, 1, 30.0,
CriticalItem.BABYDRAGON_BONES, null, null),
WYVERN_BONES(ItemID.WYVERN_BONES, "Wyvern bones", Skill.PRAYER, 1, 72.0,
CriticalItem.WYVERN_BONES, null, null),
DRAGON_BONES(ItemID.DRAGON_BONES, "Dragon bones", Skill.PRAYER, 1, 72.0,
CriticalItem.DRAGON_BONES, null, null),
FAYRG_BONES(ItemID.FAYRG_BONES, "Fayrg bones", Skill.PRAYER, 1, 84.0,
CriticalItem.FAYRG_BONES, null, null),
LAVA_DRAGON_BONES(ItemID.LAVA_DRAGON_BONES, "Lava dragon bones", Skill.PRAYER, 1, 85.0,
CriticalItem.LAVA_DRAGON_BONES, null, null),
RAURG_BONES(ItemID.RAURG_BONES, "Raurg bones", Skill.PRAYER, 1, 96.0,
CriticalItem.RAURG_BONES, null, null),
DAGANNOTH_BONES(ItemID.DAGANNOTH_BONES, "Dagannoth bones", Skill.PRAYER, 1, 125.0,
CriticalItem.DAGANNOTH_BONES, null, null),
OURG_BONES(ItemID.OURG_BONES, "Ourg bones", Skill.PRAYER, 1, 140.0,
CriticalItem.OURG_BONES, null, null),
SUPERIOR_DRAGON_BONES(ItemID.SUPERIOR_DRAGON_BONES, "Superior dragon bones", Skill.PRAYER, 1, 150.0,
CriticalItem.SUPERIOR_DRAGON_BONES, null, null),
// Shade Remains (Pyre Logs)
LOAR_REMAINS(ItemID.LOAR_REMAINS, "Shades", Skill.PRAYER, 1, 33.0, CriticalItem.LOAR_REMAINS),
PHRIN_REMAINS(ItemID.PHRIN_REMAINS, "Shades", Skill.PRAYER, 1, 46.5, CriticalItem.PHRIN_REMAINS),
RIYL_REMAINS(ItemID.RIYL_REMAINS, "Shades", Skill.PRAYER, 1, 59.5, CriticalItem.RIYL_REMAINS),
ASYN_REMAINS(ItemID.ASYN_REMAINS, "Shades", Skill.PRAYER, 1, 82.5, CriticalItem.ASYN_REMAINS),
FIYR_REMAINS(ItemID.FIYR_REMAINS, "Shades", Skill.PRAYER, 1, 84.0, CriticalItem.FIYR_REMAINS),
LOAR_REMAINS(ItemID.LOAR_REMAINS, "Loar remains", Skill.PRAYER, 1, 33.0,
CriticalItem.LOAR_REMAINS, null, null),
PHRIN_REMAINS(ItemID.PHRIN_REMAINS, "Phrin remains", Skill.PRAYER, 1, 46.5,
CriticalItem.PHRIN_REMAINS, null, null),
RIYL_REMAINS(ItemID.RIYL_REMAINS, "Riyl remains", Skill.PRAYER, 1, 59.5,
CriticalItem.RIYL_REMAINS, null, null),
ASYN_REMAINS(ItemID.ASYN_REMAINS, "Asyn remains", Skill.PRAYER, 1, 82.5,
CriticalItem.ASYN_REMAINS, null, null),
FIYR_REMAINS(ItemID.FIYR_REMAINS, "Fiyre remains", Skill.PRAYER, 1, 84.0,
CriticalItem.FIYR_REMAINS, null, null),
// Ensouled Heads
ENSOULED_GOBLIN_HEAD(ItemID.ENSOULED_GOBLIN_HEAD_13448, "Ensouled Heads", Skill.PRAYER, 1, 130.0, CriticalItem.ENSOULED_GOBLIN_HEAD),
ENSOULED_MONKEY_HEAD(ItemID.ENSOULED_MONKEY_HEAD_13451, "Ensouled Heads", Skill.PRAYER, 1, 182.0, CriticalItem.ENSOULED_MONKEY_HEAD),
ENSOULED_IMP_HEAD(ItemID.ENSOULED_IMP_HEAD_13454, "Ensouled Heads", Skill.PRAYER, 1, 286.0, CriticalItem.ENSOULED_IMP_HEAD),
ENSOULED_MINOTAUR_HEAD(ItemID.ENSOULED_MINOTAUR_HEAD_13457, "Ensouled Heads", Skill.PRAYER, 1, 364.0, CriticalItem.ENSOULED_MINOTAUR_HEAD),
ENSOULED_SCORPION_HEAD(ItemID.ENSOULED_SCORPION_HEAD_13460, "Ensouled Heads", Skill.PRAYER, 1, 454.0, CriticalItem.ENSOULED_SCORPION_HEAD),
ENSOULED_BEAR_HEAD(ItemID.ENSOULED_BEAR_HEAD_13463, "Ensouled Heads", Skill.PRAYER, 1, 480.0, CriticalItem.ENSOULED_BEAR_HEAD),
ENSOULED_UNICORN_HEAD(ItemID.ENSOULED_UNICORN_HEAD_13466, "Ensouled Heads", Skill.PRAYER, 1, 494.0, CriticalItem.ENSOULED_UNICORN_HEAD),
ENSOULED_DOG_HEAD(ItemID.ENSOULED_DOG_HEAD_13469, "Ensouled Heads", Skill.PRAYER, 1, 520.0, CriticalItem.ENSOULED_DOG_HEAD),
ENSOULED_CHAOS_DRUID_HEAD(ItemID.ENSOULED_CHAOS_DRUID_HEAD_13472, "Ensouled Heads", Skill.PRAYER, 1, 584.0, CriticalItem.ENSOULED_CHAOS_DRUID_HEAD),
ENSOULED_GIANT_HEAD(ItemID.ENSOULED_GIANT_HEAD_13475, "Ensouled Heads", Skill.PRAYER, 1, 650.0, CriticalItem.ENSOULED_GIANT_HEAD),
ENSOULED_OGRE_HEAD(ItemID.ENSOULED_OGRE_HEAD_13478, "Ensouled Heads", Skill.PRAYER, 1, 716.0, CriticalItem.ENSOULED_OGRE_HEAD),
ENSOULED_ELF_HEAD(ItemID.ENSOULED_ELF_HEAD_13481, "Ensouled Heads", Skill.PRAYER, 1, 754.0, CriticalItem.ENSOULED_ELF_HEAD),
ENSOULED_TROLL_HEAD(ItemID.ENSOULED_TROLL_HEAD_13484, "Ensouled Heads", Skill.PRAYER, 1, 780.0, CriticalItem.ENSOULED_TROLL_HEAD),
ENSOULED_HORROR_HEAD(ItemID.ENSOULED_HORROR_HEAD_13487, "Ensouled Heads", Skill.PRAYER, 1, 832.0, CriticalItem.ENSOULED_HORROR_HEAD),
ENSOULED_KALPHITE_HEAD(ItemID.ENSOULED_KALPHITE_HEAD_13490, "Ensouled Heads", Skill.PRAYER, 1, 884.0, CriticalItem.ENSOULED_KALPHITE_HEAD),
ENSOULED_DAGANNOTH_HEAD(ItemID.ENSOULED_DAGANNOTH_HEAD_13493, "Ensouled Heads", Skill.PRAYER, 1, 936.0, CriticalItem.ENSOULED_DAGANNOTH_HEAD),
ENSOULED_BLOODVELD_HEAD(ItemID.ENSOULED_BLOODVELD_HEAD_13496, "Ensouled Heads", Skill.PRAYER, 1, 1040.0, CriticalItem.ENSOULED_BLOODVELD_HEAD),
ENSOULED_TZHAAR_HEAD(ItemID.ENSOULED_TZHAAR_HEAD_13499, "Ensouled Heads", Skill.PRAYER, 1, 1104.0, CriticalItem.ENSOULED_TZHAAR_HEAD),
ENSOULED_DEMON_HEAD(ItemID.ENSOULED_DEMON_HEAD_13502, "Ensouled Heads", Skill.PRAYER, 1, 1170.0, CriticalItem.ENSOULED_DEMON_HEAD),
ENSOULED_AVIANSIE_HEAD(ItemID.ENSOULED_AVIANSIE_HEAD_13505, "Ensouled Heads", Skill.PRAYER, 1, 1234.0, CriticalItem.ENSOULED_AVIANSIE_HEAD),
ENSOULED_ABYSSAL_HEAD(ItemID.ENSOULED_ABYSSAL_HEAD_13508, "Ensouled Heads", Skill.PRAYER, 1, 1300.0, CriticalItem.ENSOULED_ABYSSAL_HEAD),
ENSOULED_DRAGON_HEAD(ItemID.ENSOULED_DRAGON_HEAD_13511, "Ensouled Heads", Skill.PRAYER, 1, 1560.0, CriticalItem.ENSOULED_DRAGON_HEAD),
ENSOULED_GOBLIN_HEAD(ItemID.ENSOULED_GOBLIN_HEAD_13448, "Ensouled goblin head", Skill.PRAYER, 1, 130.0,
CriticalItem.ENSOULED_GOBLIN_HEAD, null, null),
ENSOULED_MONKEY_HEAD(ItemID.ENSOULED_MONKEY_HEAD_13451, "Ensouled monkey head", Skill.PRAYER, 1, 182.0,
CriticalItem.ENSOULED_MONKEY_HEAD, null, null),
ENSOULED_IMP_HEAD(ItemID.ENSOULED_IMP_HEAD_13454, "Ensouled imp head", Skill.PRAYER, 1, 286.0,
CriticalItem.ENSOULED_IMP_HEAD, null, null),
ENSOULED_MINOTAUR_HEAD(ItemID.ENSOULED_MINOTAUR_HEAD_13457, "Ensouled minotaur head", Skill.PRAYER, 1, 364.0,
CriticalItem.ENSOULED_MINOTAUR_HEAD, null, null),
ENSOULED_SCORPION_HEAD(ItemID.ENSOULED_SCORPION_HEAD_13460, "Ensouled scorpion head", Skill.PRAYER, 1, 454.0,
CriticalItem.ENSOULED_SCORPION_HEAD, null, null),
ENSOULED_BEAR_HEAD(ItemID.ENSOULED_BEAR_HEAD_13463, "Ensouled bear head", Skill.PRAYER, 1, 480.0,
CriticalItem.ENSOULED_BEAR_HEAD, null, null),
ENSOULED_UNICORN_HEAD(ItemID.ENSOULED_UNICORN_HEAD_13466, "Ensouled unicorn head", Skill.PRAYER, 1, 494.0,
CriticalItem.ENSOULED_UNICORN_HEAD, null, null),
ENSOULED_DOG_HEAD(ItemID.ENSOULED_DOG_HEAD_13469, "Ensouled dog head", Skill.PRAYER, 1, 520.0,
CriticalItem.ENSOULED_DOG_HEAD, null, null),
ENSOULED_CHAOS_DRUID_HEAD(ItemID.ENSOULED_CHAOS_DRUID_HEAD_13472, "Ensouled druid head", Skill.PRAYER, 1, 584.0,
CriticalItem.ENSOULED_CHAOS_DRUID_HEAD, null, null),
ENSOULED_GIANT_HEAD(ItemID.ENSOULED_GIANT_HEAD_13475, "Ensouled giant head", Skill.PRAYER, 1, 650.0,
CriticalItem.ENSOULED_GIANT_HEAD, null, null),
ENSOULED_OGRE_HEAD(ItemID.ENSOULED_OGRE_HEAD_13478, "Ensouled ogre head", Skill.PRAYER, 1, 716.0,
CriticalItem.ENSOULED_OGRE_HEAD, null, null),
ENSOULED_ELF_HEAD(ItemID.ENSOULED_ELF_HEAD_13481, "Ensouled elf head", Skill.PRAYER, 1, 754.0,
CriticalItem.ENSOULED_ELF_HEAD, null, null),
ENSOULED_TROLL_HEAD(ItemID.ENSOULED_TROLL_HEAD_13484, "Ensouled troll head", Skill.PRAYER, 1, 780.0,
CriticalItem.ENSOULED_TROLL_HEAD, null, null),
ENSOULED_HORROR_HEAD(ItemID.ENSOULED_HORROR_HEAD_13487, "Ensouled horror head", Skill.PRAYER, 1, 832.0,
CriticalItem.ENSOULED_HORROR_HEAD, null, null),
ENSOULED_KALPHITE_HEAD(ItemID.ENSOULED_KALPHITE_HEAD_13490, "Ensouled kalphite head", Skill.PRAYER, 1, 884.0,
CriticalItem.ENSOULED_KALPHITE_HEAD, null, null),
ENSOULED_DAGANNOTH_HEAD(ItemID.ENSOULED_DAGANNOTH_HEAD_13493, "Ensouled dagannoth head", Skill.PRAYER, 1, 936.0,
CriticalItem.ENSOULED_DAGANNOTH_HEAD, null, null),
ENSOULED_BLOODVELD_HEAD(ItemID.ENSOULED_BLOODVELD_HEAD_13496, "Ensouled bloodveld head", Skill.PRAYER, 1, 1040.0,
CriticalItem.ENSOULED_BLOODVELD_HEAD, null, null),
ENSOULED_TZHAAR_HEAD(ItemID.ENSOULED_TZHAAR_HEAD_13499, "Ensouled tzhaar head", Skill.PRAYER, 1, 1104.0,
CriticalItem.ENSOULED_TZHAAR_HEAD, null, null),
ENSOULED_DEMON_HEAD(ItemID.ENSOULED_DEMON_HEAD_13502, "Ensouled demon head", Skill.PRAYER, 1, 1170.0,
CriticalItem.ENSOULED_DEMON_HEAD, null, null),
ENSOULED_AVIANSIE_HEAD(ItemID.ENSOULED_AVIANSIE_HEAD_13505, "Ensouled aviansie head", Skill.PRAYER, 1, 1234.0,
CriticalItem.ENSOULED_AVIANSIE_HEAD, null, null),
ENSOULED_ABYSSAL_HEAD(ItemID.ENSOULED_ABYSSAL_HEAD_13508, "Ensouled abyssal head", Skill.PRAYER, 1, 1300.0,
CriticalItem.ENSOULED_ABYSSAL_HEAD, null, null),
ENSOULED_DRAGON_HEAD(ItemID.ENSOULED_DRAGON_HEAD_13511, "Ensouled dragon head", Skill.PRAYER, 1, 1560.0,
CriticalItem.ENSOULED_DRAGON_HEAD, null, null),
/*
* Cooking Items
*/
RAW_HERRING(ItemID.RAW_HERRING, "Fish", Skill.COOKING, 5, 50.0, CriticalItem.RAW_HERRING),
RAW_MACKEREL(ItemID.RAW_MACKEREL, "Fish", Skill.COOKING, 10, 60.0, CriticalItem.RAW_MACKEREL),
RAW_TROUT(ItemID.RAW_TROUT, "Fish", Skill.COOKING, 15, 70.0, CriticalItem.RAW_TROUT),
RAW_COD(ItemID.RAW_COD, "Fish", Skill.COOKING, 18, 75.0, CriticalItem.RAW_COD),
RAW_PIKE(ItemID.RAW_PIKE, "Fish", Skill.COOKING, 20, 80.0, CriticalItem.RAW_PIKE),
RAW_SALMON(ItemID.RAW_SALMON, "Fish", Skill.COOKING, 25, 90.0, CriticalItem.RAW_SALMON),
RAW_TUNA(ItemID.RAW_TUNA, "Fish", Skill.COOKING, 30, 100.0, CriticalItem.RAW_TUNA),
RAW_KARAMBWAN(ItemID.RAW_KARAMBWAN, "Fish", Skill.COOKING, 30, 190.0, CriticalItem.RAW_KARAMBWAN),
RAW_LOBSTER(ItemID.RAW_LOBSTER, "Fish", Skill.COOKING, 40, 120.0, CriticalItem.RAW_LOBSTER),
RAW_BASS(ItemID.RAW_BASS, "Fish", Skill.COOKING, 43, 130.0, CriticalItem.RAW_BASS),
RAW_SWORDFISH(ItemID.RAW_SWORDFISH, "Fish", Skill.COOKING, 45, 140.0, CriticalItem.RAW_SWORDFISH),
RAW_MONKFISH(ItemID.RAW_MONKFISH, "Fish", Skill.COOKING, 62, 150.0, CriticalItem.RAW_MONKFISH),
RAW_SHARK(ItemID.RAW_SHARK, "Fish", Skill.COOKING, 80, 210.0, CriticalItem.RAW_SHARK),
RAW_SEA_TURTLE(ItemID.RAW_SEA_TURTLE, "Fish", Skill.COOKING, 82, 211.3, CriticalItem.RAW_SEA_TURTLE),
RAW_ANGLERFISH(ItemID.RAW_ANGLERFISH, "Fish", Skill.COOKING, 84, 230.0, CriticalItem.RAW_ANGLERFISH),
RAW_DARK_CRAB(ItemID.RAW_DARK_CRAB, "Fish", Skill.COOKING, 90, 215.0, CriticalItem.RAW_DARK_CRAB),
RAW_MANTA_RAY(ItemID.RAW_MANTA_RAY, "Fish", Skill.COOKING, 91, 216.2, CriticalItem.RAW_MANTA_RAY),
COOK_HERRING(ItemID.HERRING, "Herring", Skill.COOKING, 5, 50.0,
CriticalItem.RAW_HERRING, null, new ItemStack(ItemID.HERRING, 1)),
COOK_MACKEREL(ItemID.MACKEREL, "Mackerel", Skill.COOKING, 10, 60.0,
CriticalItem.RAW_MACKEREL, null, new ItemStack(ItemID.MACKEREL, 1)),
COOK_TROUT(ItemID.TROUT, "Trout", Skill.COOKING, 15, 70.0,
CriticalItem.RAW_TROUT, null, new ItemStack(ItemID.TROUT, 1)),
COOK_COD(ItemID.COD, "Cod", Skill.COOKING, 18, 75.0,
CriticalItem.RAW_COD, null, new ItemStack(ItemID.COD, 1)),
COOK_PIKE(ItemID.PIKE, "Pike", Skill.COOKING, 20, 80.0,
CriticalItem.RAW_PIKE, null, new ItemStack(ItemID.PIKE, 1)),
COOK_SALMON(ItemID.SALMON, "Salmon", Skill.COOKING, 25, 90.0,
CriticalItem.RAW_SALMON, null, new ItemStack(ItemID.SALMON, 1)),
COOK_TUNA(ItemID.TUNA, "Tuna", Skill.COOKING, 30, 100.0,
CriticalItem.RAW_TUNA, null, new ItemStack(ItemID.TUNA, 1)),
COOK_KARAMBWAN(ItemID.COOKED_KARAMBWAN, "Cooked Karambwan", Skill.COOKING, 30, 190.0,
CriticalItem.RAW_KARAMBWAN, null, new ItemStack(ItemID.COOKED_KARAMBWAN, 1)),
COOK_LOBSTER(ItemID.LOBSTER, "Lobster", Skill.COOKING, 40, 120.0,
CriticalItem.RAW_LOBSTER, null, new ItemStack(ItemID.LOBSTER, 1)),
COOK_BASS(ItemID.BASS, "Bass", Skill.COOKING, 43, 130.0,
CriticalItem.RAW_BASS, null, new ItemStack(ItemID.BASS, 1)),
COOK_SWORDFISH(ItemID.SWORDFISH, "Swordfish", Skill.COOKING, 45, 140.0,
CriticalItem.RAW_SWORDFISH, null, new ItemStack(ItemID.SWORDFISH, 1)),
COOK_MONKFISH(ItemID.MONKFISH, "Monkfish", Skill.COOKING, 62, 150.0,
CriticalItem.RAW_MONKFISH, null, new ItemStack(ItemID.MONKFISH, 1)),
COOK_SHARK(ItemID.SHARK, "Shark", Skill.COOKING, 80, 210.0,
CriticalItem.RAW_SHARK, null, new ItemStack(ItemID.SHARK, 1)),
COOK_SEA_TURTLE(ItemID.SEA_TURTLE, "Sea turtle", Skill.COOKING, 82, 211.3,
CriticalItem.RAW_SEA_TURTLE, null, new ItemStack(ItemID.SEA_TURTLE, 1)),
COOK_ANGLERFISH(ItemID.ANGLERFISH, "Anglerfish", Skill.COOKING, 84, 230.0,
CriticalItem.RAW_ANGLERFISH, null, new ItemStack(ItemID.ANGLERFISH, 1)),
COOK_DARK_CRAB(ItemID.DARK_CRAB, "Dark crab", Skill.COOKING, 90, 215.0,
CriticalItem.RAW_DARK_CRAB, null, new ItemStack(ItemID.DARK_CRAB, 1)),
COOK_MANTA_RAY(ItemID.MANTA_RAY, "Manta ray", Skill.COOKING, 91, 216.2,
CriticalItem.RAW_MANTA_RAY, null, new ItemStack(ItemID.MANTA_RAY, 1)),
WINE(ItemID.JUG_OF_WINE, "Other", Skill.COOKING, 35, 200, CriticalItem.GRAPES, ActivitySecondaries.JUG_OF_WATER),
WINE(ItemID.JUG_OF_WINE, "Jug of wine", Skill.COOKING, 35, 200,
CriticalItem.GRAPES, Secondaries.JUG_OF_WATER, new ItemStack(ItemID.JUG_OF_WINE, 1)),
/*
* Crafting Items
*/
// Spinning
BALL_OF_WOOL(ItemID.WOOL, "Misc", Skill.CRAFTING, 1, 2.5, CriticalItem.WOOL),
BOW_STRING(ItemID.BOW_STRING, "Misc", Skill.CRAFTING, 1, 15, CriticalItem.FLAX),
BALL_OF_WOOL(ItemID.BALL_OF_WOOL, "Ball of wool", Skill.CRAFTING, 1, 2.5,
CriticalItem.WOOL, null, new ItemStack(ItemID.BALL_OF_WOOL, 1)),
BOW_STRING(ItemID.BOW_STRING, "Bow string", Skill.CRAFTING, 1, 15,
CriticalItem.FLAX, null, new ItemStack(ItemID.BOW_STRING, 1)),
// Glass Blowing
BEER_GLASS(ItemID.BEER_GLASS, "Beer Glass", Skill.CRAFTING, 1, 17.5, CriticalItem.MOLTEN_GLASS),
CANDLE_LANTERN(ItemID.CANDLE_LANTERN, "Candle Lantern", Skill.CRAFTING, 4, 19, CriticalItem.MOLTEN_GLASS),
OIL_LAMP(ItemID.OIL_LAMP, "Oil Lamp", Skill.CRAFTING, 12, 25, CriticalItem.MOLTEN_GLASS),
VIAL(ItemID.VIAL, "Vial", Skill.CRAFTING, 33, 35, CriticalItem.MOLTEN_GLASS),
EMPTY_FISHBOWL(ItemID.EMPTY_FISHBOWL, "Empty fishbowl", Skill.CRAFTING, 42, 42.5, CriticalItem.MOLTEN_GLASS),
UNPOWERED_ORB(ItemID.UNPOWERED_ORB, "Unpowered orb", Skill.CRAFTING, 46, 52.5, CriticalItem.MOLTEN_GLASS),
LANTERN_LENS(ItemID.LANTERN_LENS, "Lantern lens", Skill.CRAFTING, 49, 55, CriticalItem.MOLTEN_GLASS),
LIGHT_ORB(ItemID.LIGHT_ORB, "Light orb", Skill.CRAFTING, 87, 70, CriticalItem.MOLTEN_GLASS),
BEER_GLASS(ItemID.BEER_GLASS, "Beer glass", Skill.CRAFTING, 1, 17.5,
CriticalItem.MOLTEN_GLASS, null, new ItemStack(ItemID.BEER_GLASS, 1)),
CANDLE_LANTERN(ItemID.CANDLE_LANTERN, "Candle lantern", Skill.CRAFTING, 4, 19,
CriticalItem.MOLTEN_GLASS, null, new ItemStack(ItemID.CANDLE_LANTERN, 1)),
OIL_LAMP(ItemID.OIL_LAMP, "Oil lamp", Skill.CRAFTING, 12, 25,
CriticalItem.MOLTEN_GLASS, null, new ItemStack(ItemID.OIL_LAMP, 1)),
VIAL(ItemID.VIAL, "Vial", Skill.CRAFTING, 33, 35,
CriticalItem.MOLTEN_GLASS, null, new ItemStack(ItemID.VIAL, 1)),
EMPTY_FISHBOWL(ItemID.EMPTY_FISHBOWL, "Empty fishbowl", Skill.CRAFTING, 42, 42.5,
CriticalItem.MOLTEN_GLASS, null, new ItemStack(ItemID.EMPTY_FISHBOWL, 1)),
UNPOWERED_ORB(ItemID.UNPOWERED_ORB, "Unpowered orb", Skill.CRAFTING, 46, 52.5,
CriticalItem.MOLTEN_GLASS, null, new ItemStack(ItemID.UNPOWERED_ORB, 1)),
LANTERN_LENS(ItemID.LANTERN_LENS, "Lantern lens", Skill.CRAFTING, 49, 55,
CriticalItem.MOLTEN_GLASS, null, new ItemStack(ItemID.LANTERN_LENS, 1)),
LIGHT_ORB(ItemID.LIGHT_ORB, "Light orb", Skill.CRAFTING, 87, 70,
CriticalItem.MOLTEN_GLASS, null, new ItemStack(ItemID.LIGHT_ORB, 1)),
// D'hide/Dragon Leather
GREEN_DRAGON_LEATHER(ItemID.GREEN_DRAGON_LEATHER, "D'hide", Skill.CRAFTING, 57, 62.0, CriticalItem.GREEN_DRAGON_LEATHER),
BLUE_DRAGON_LEATHER(ItemID.BLUE_DRAGON_LEATHER, "D'hide", Skill.CRAFTING, 66, 70.0, CriticalItem.BLUE_DRAGON_LEATHER),
RED_DRAGON_LEATHER(ItemID.RED_DRAGON_LEATHER, "D'hide", Skill.CRAFTING, 73, 78.0, CriticalItem.RED_DRAGON_LEATHER),
BLACK_DRAGON_LEATHER(ItemID.BLACK_DRAGON_LEATHER, "D'hide", Skill.CRAFTING, 79, 86.0, CriticalItem.BLACK_DRAGON_LEATHER),
GREEN_DRAGONHIDE(ItemID.GREEN_DRAGON_LEATHER, "Tan Green D'hide", Skill.CRAFTING, 57, 0,
CriticalItem.GREEN_DRAGONHIDE, null, new ItemStack(ItemID.GREEN_DRAGON_LEATHER, 1)),
BLUE_DRAGONHIDE(ItemID.BLUE_DRAGON_LEATHER, "Tan Blue D'hide", Skill.CRAFTING, 66, 0,
CriticalItem.BLUE_DRAGONHIDE, null, new ItemStack(ItemID.BLUE_DRAGON_LEATHER, 1)),
RED_DRAGONHIDE(ItemID.RED_DRAGON_LEATHER, "Tan Red D'hide", Skill.CRAFTING, 73, 0,
CriticalItem.RED_DRAGONHIDE, null, new ItemStack(ItemID.RED_DRAGON_LEATHER, 1)),
BLACK_DRAGONHIDE(ItemID.BLACK_DRAGON_LEATHER, "Tan Black D'hide", Skill.CRAFTING, 79, 0,
CriticalItem.BLACK_DRAGONHIDE, null, new ItemStack(ItemID.BLACK_DRAGON_LEATHER, 1)),
GREEN_DRAGON_LEATHER(ItemID.GREEN_DHIDE_VAMB, "Green D'hide product", Skill.CRAFTING, 57, 62.0,
CriticalItem.GREEN_DRAGON_LEATHER, null, null),
BLUE_DRAGON_LEATHER(ItemID.BLUE_DHIDE_VAMB, "Blue D'hide product", Skill.CRAFTING, 66, 70.0,
CriticalItem.BLUE_DRAGON_LEATHER, null, null),
RED_DRAGON_LEATHER(ItemID.RED_DHIDE_VAMB, "Red D'hide product", Skill.CRAFTING, 73, 78.0,
CriticalItem.RED_DRAGON_LEATHER, null, null),
BLACK_DRAGON_LEATHER(ItemID.BLACK_DHIDE_VAMB, "Black D'hide product", Skill.CRAFTING, 79, 86.0,
CriticalItem.BLACK_DRAGON_LEATHER, null, null),
// Uncut Gems
UNCUT_OPAL(ItemID.UNCUT_OPAL, "Gems", Skill.CRAFTING, 1, 15.0, CriticalItem.UNCUT_OPAL),
UNCUT_JADE(ItemID.UNCUT_JADE, "Gems", Skill.CRAFTING, 13, 20.0, CriticalItem.UNCUT_JADE),
UNCUT_RED_TOPAZ(ItemID.UNCUT_RED_TOPAZ, "Gems", Skill.CRAFTING, 16, 25.0, CriticalItem.UNCUT_RED_TOPAZ),
UNCUT_SAPPHIRE(ItemID.UNCUT_SAPPHIRE, "Gems", Skill.CRAFTING, 20, 50.0, CriticalItem.UNCUT_SAPPHIRE),
UNCUT_EMERALD(ItemID.UNCUT_EMERALD, "Gems", Skill.CRAFTING, 27, 67.5, CriticalItem.UNCUT_EMERALD),
UNCUT_RUBY(ItemID.UNCUT_RUBY, "Gems", Skill.CRAFTING, 34, 85, CriticalItem.UNCUT_RUBY),
UNCUT_DIAMOND(ItemID.UNCUT_DIAMOND, "Gems", Skill.CRAFTING, 43, 107.5, CriticalItem.UNCUT_DIAMOND),
UNCUT_DRAGONSTONE(ItemID.UNCUT_DRAGONSTONE, "Gems", Skill.CRAFTING, 55, 137.5, CriticalItem.UNCUT_DRAGONSTONE),
UNCUT_ONYX(ItemID.UNCUT_ONYX, "Gems", Skill.CRAFTING, 67, 167.5, CriticalItem.UNCUT_ONYX),
UNCUT_ZENYTE(ItemID.UNCUT_ZENYTE, "Gems", Skill.CRAFTING, 89, 200.0, CriticalItem.UNCUT_ZENYTE),
UNCUT_OPAL(ItemID.OPAL, "Cut opal", Skill.CRAFTING, 1, 15.0,
CriticalItem.UNCUT_OPAL, null, new ItemStack(ItemID.OPAL, 1)),
UNCUT_JADE(ItemID.JADE, "Cut jade", Skill.CRAFTING, 13, 20.0,
CriticalItem.UNCUT_JADE, null, new ItemStack(ItemID.JADE, 1)),
UNCUT_RED_TOPAZ(ItemID.RED_TOPAZ, "Cut red topaz", Skill.CRAFTING, 16, 25.0,
CriticalItem.UNCUT_RED_TOPAZ, null, new ItemStack(ItemID.RED_TOPAZ, 1)),
UNCUT_SAPPHIRE(ItemID.SAPPHIRE, "Cut sapphire", Skill.CRAFTING, 20, 50.0,
CriticalItem.UNCUT_SAPPHIRE, null, new ItemStack(ItemID.SAPPHIRE, 1)),
UNCUT_EMERALD(ItemID.EMERALD, "Cut emerald", Skill.CRAFTING, 27, 67.5,
CriticalItem.UNCUT_EMERALD, null, new ItemStack(ItemID.EMERALD, 1)),
UNCUT_RUBY(ItemID.RUBY, "Cut ruby", Skill.CRAFTING, 34, 85,
CriticalItem.UNCUT_RUBY, null, new ItemStack(ItemID.RUBY, 1)),
UNCUT_DIAMOND(ItemID.DIAMOND, "Cut diamond", Skill.CRAFTING, 43, 107.5,
CriticalItem.UNCUT_DIAMOND, null, new ItemStack(ItemID.DIAMOND, 1)),
UNCUT_DRAGONSTONE(ItemID.DRAGONSTONE, "Cut dragonstone", Skill.CRAFTING, 55, 137.5,
CriticalItem.UNCUT_DRAGONSTONE, null, new ItemStack(ItemID.DRAGONSTONE, 1)),
UNCUT_ONYX(ItemID.ONYX, "Cut onyx", Skill.CRAFTING, 67, 167.5,
CriticalItem.UNCUT_ONYX, null, new ItemStack(ItemID.ONYX, 1)),
UNCUT_ZENYTE(ItemID.ZENYTE, "Cut zenyte", Skill.CRAFTING, 89, 200.0,
CriticalItem.UNCUT_ZENYTE, null, new ItemStack(ItemID.ZENYTE, 1)),
// Silver Jewelery
OPAL_RING(ItemID.OPAL_RING, "Opal ring", Skill.CRAFTING, 1, 10, CriticalItem.OPAL, ActivitySecondaries.SILVER_BAR),
OPAL_NECKLACE(ItemID.OPAL_NECKLACE, "Opal necklace", Skill.CRAFTING, 16, 35, CriticalItem.OPAL, ActivitySecondaries.SILVER_BAR),
OPAL_BRACELET(ItemID.OPAL_BRACELET, "Opal bracelet", Skill.CRAFTING, 22, 45, CriticalItem.OPAL, ActivitySecondaries.SILVER_BAR),
OPAL_AMULET(ItemID.OPAL_AMULET, "Opal amulet", Skill.CRAFTING, 27, 55, CriticalItem.OPAL, ActivitySecondaries.SILVER_BAR),
JADE_RING(ItemID.JADE_RING, "Jade ring", Skill.CRAFTING, 13, 32, CriticalItem.JADE, ActivitySecondaries.SILVER_BAR),
JADE_NECKLACE(ItemID.JADE_NECKLACE, "Jade necklace", Skill.CRAFTING, 25, 54, CriticalItem.JADE, ActivitySecondaries.SILVER_BAR),
JADE_BRACELET(ItemID.JADE_BRACELET, "Jade bracelet", Skill.CRAFTING, 29, 60, CriticalItem.JADE, ActivitySecondaries.SILVER_BAR),
JADE_AMULET(ItemID.JADE_AMULET, "Jade amulet", Skill.CRAFTING, 34, 70, CriticalItem.JADE, ActivitySecondaries.SILVER_BAR),
TOPAZ_RING(ItemID.TOPAZ_RING, "Topaz ring", Skill.CRAFTING, 16, 35, CriticalItem.RED_TOPAZ, ActivitySecondaries.SILVER_BAR),
TOPAZ_NECKLACE(ItemID.TOPAZ_NECKLACE, "Topaz necklace", Skill.CRAFTING, 32, 70, CriticalItem.RED_TOPAZ, ActivitySecondaries.SILVER_BAR),
TOPAZ_BRACELET(ItemID.TOPAZ_BRACELET, "Topaz bracelet", Skill.CRAFTING, 38, 75, CriticalItem.RED_TOPAZ, ActivitySecondaries.SILVER_BAR),
TOPAZ_AMULET(ItemID.TOPAZ_AMULET, "Topaz amulet", Skill.CRAFTING, 45, 80, CriticalItem.RED_TOPAZ, ActivitySecondaries.SILVER_BAR),
OPAL_RING(ItemID.OPAL_RING, "Opal ring", Skill.CRAFTING, 1, 10,
CriticalItem.OPAL, Secondaries.SILVER_BAR, new ItemStack(ItemID.OPAL_RING, 1)),
OPAL_NECKLACE(ItemID.OPAL_NECKLACE, "Opal necklace", Skill.CRAFTING, 16, 35,
CriticalItem.OPAL, Secondaries.SILVER_BAR, new ItemStack(ItemID.OPAL_NECKLACE, 1)),
OPAL_BRACELET(ItemID.OPAL_BRACELET, "Opal bracelet", Skill.CRAFTING, 22, 45,
CriticalItem.OPAL, Secondaries.SILVER_BAR, new ItemStack(ItemID.OPAL_BRACELET, 1)),
OPAL_AMULET(ItemID.OPAL_AMULET, "Opal amulet", Skill.CRAFTING, 27, 55,
CriticalItem.OPAL, Secondaries.SILVER_BAR, new ItemStack(ItemID.OPAL_AMULET, 1)),
JADE_RING(ItemID.JADE_RING, "Jade ring", Skill.CRAFTING, 13, 32,
CriticalItem.JADE, Secondaries.SILVER_BAR, new ItemStack(ItemID.JADE_RING, 1)),
JADE_NECKLACE(ItemID.JADE_NECKLACE, "Jade necklace", Skill.CRAFTING, 25, 54,
CriticalItem.JADE, Secondaries.SILVER_BAR, new ItemStack(ItemID.JADE_NECKLACE, 1)),
JADE_BRACELET(ItemID.JADE_BRACELET, "Jade bracelet", Skill.CRAFTING, 29, 60,
CriticalItem.JADE, Secondaries.SILVER_BAR, new ItemStack(ItemID.JADE_BRACELET, 1)),
JADE_AMULET(ItemID.JADE_AMULET, "Jade amulet", Skill.CRAFTING, 34, 70,
CriticalItem.JADE, Secondaries.SILVER_BAR, new ItemStack(ItemID.JADE_AMULET, 1)),
TOPAZ_RING(ItemID.TOPAZ_RING, "Topaz ring", Skill.CRAFTING, 16, 35,
CriticalItem.RED_TOPAZ, Secondaries.SILVER_BAR, new ItemStack(ItemID.TOPAZ_RING, 1)),
TOPAZ_NECKLACE(ItemID.TOPAZ_NECKLACE, "Topaz necklace", Skill.CRAFTING, 32, 70,
CriticalItem.RED_TOPAZ, Secondaries.SILVER_BAR, new ItemStack(ItemID.TOPAZ_NECKLACE, 1)),
TOPAZ_BRACELET(ItemID.TOPAZ_BRACELET, "Topaz bracelet", Skill.CRAFTING, 38, 75,
CriticalItem.RED_TOPAZ, Secondaries.SILVER_BAR, new ItemStack(ItemID.TOPAZ_BRACELET, 1)),
TOPAZ_AMULET(ItemID.TOPAZ_AMULET, "Topaz amulet", Skill.CRAFTING, 45, 80,
CriticalItem.RED_TOPAZ, Secondaries.SILVER_BAR, new ItemStack(ItemID.TOPAZ_AMULET, 1)),
// Gold Jewelery
SAPPHIRE_RING(ItemID.SAPPHIRE_RING, "Sapphire ring", Skill.CRAFTING, 20, 40, CriticalItem.SAPPHIRE, ActivitySecondaries.GOLD_BAR),
SAPPHIRE_NECKLACE(ItemID.SAPPHIRE_NECKLACE, "Sapphire necklace", Skill.CRAFTING, 22, 55, CriticalItem.SAPPHIRE, ActivitySecondaries.GOLD_BAR),
SAPPHIRE_BRACELET(ItemID.SAPPHIRE_BRACELET, "Sapphire bracelet", Skill.CRAFTING, 23, 60, CriticalItem.SAPPHIRE, ActivitySecondaries.GOLD_BAR),
SAPPHIRE_AMULET(ItemID.SAPPHIRE_AMULET, "Sapphire amulet", Skill.CRAFTING, 24, 65, CriticalItem.SAPPHIRE, ActivitySecondaries.GOLD_BAR),
EMERALD_RING(ItemID.EMERALD_RING, "Emerald ring", Skill.CRAFTING, 27, 55, CriticalItem.EMERALD, ActivitySecondaries.GOLD_BAR),
EMERALD_NECKLACE(ItemID.EMERALD_NECKLACE, "Emerald necklace", Skill.CRAFTING, 29, 60, CriticalItem.EMERALD, ActivitySecondaries.GOLD_BAR),
EMERALD_BRACELET(ItemID.EMERALD_BRACELET, "Emerald bracelet", Skill.CRAFTING, 30, 65, CriticalItem.EMERALD, ActivitySecondaries.GOLD_BAR),
EMERALD_AMULET(ItemID.EMERALD_AMULET, "Emerald amulet", Skill.CRAFTING, 31, 70, CriticalItem.EMERALD, ActivitySecondaries.GOLD_BAR),
RUBY_RING(ItemID.RUBY_RING, "Ruby ring", Skill.CRAFTING, 34, 70, CriticalItem.RUBY, ActivitySecondaries.GOLD_BAR),
RUBY_NECKLACE(ItemID.RUBY_NECKLACE, "Ruby necklace", Skill.CRAFTING, 40, 75, CriticalItem.RUBY, ActivitySecondaries.GOLD_BAR),
RUBY_BRACELET(ItemID.RUBY_BRACELET, "Ruby bracelet", Skill.CRAFTING, 42, 80, CriticalItem.RUBY, ActivitySecondaries.GOLD_BAR),
RUBY_AMULET(ItemID.RUBY_AMULET, "Ruby amulet", Skill.CRAFTING, 50, 85, CriticalItem.RUBY, ActivitySecondaries.GOLD_BAR),
DIAMOND_RING(ItemID.DIAMOND_RING, "Diamond ring", Skill.CRAFTING, 43, 85, CriticalItem.DIAMOND, ActivitySecondaries.GOLD_BAR),
DIAMOND_NECKLACE(ItemID.DIAMOND_NECKLACE, "Diamond necklace", Skill.CRAFTING, 56, 90, CriticalItem.DIAMOND, ActivitySecondaries.GOLD_BAR),
DIAMOND_BRACELET(ItemID.DIAMOND_BRACELET, "Diamond bracelet", Skill.CRAFTING, 58, 95, CriticalItem.DIAMOND, ActivitySecondaries.GOLD_BAR),
DIAMOND_AMULET(ItemID.DIAMOND_AMULET, "Diamond amulet", Skill.CRAFTING, 70, 100, CriticalItem.DIAMOND, ActivitySecondaries.GOLD_BAR),
DRAGONSTONE_RING(ItemID.DRAGONSTONE_RING, "Dragonstone ring", Skill.CRAFTING, 55, 100, CriticalItem.DRAGONSTONE, ActivitySecondaries.GOLD_BAR),
DRAGON_NECKLACE(ItemID.DRAGON_NECKLACE, "Dragon necklace", Skill.CRAFTING, 72, 105, CriticalItem.DRAGONSTONE, ActivitySecondaries.GOLD_BAR),
DRAGONSTONE_BRACELET(ItemID.DRAGONSTONE_BRACELET, "Dragonstone bracelet", Skill.CRAFTING, 74, 110, CriticalItem.DRAGONSTONE, ActivitySecondaries.GOLD_BAR),
DRAGONSTONE_AMULET(ItemID.DRAGONSTONE_AMULET, "Dragonstone amulet", Skill.CRAFTING, 80, 150, CriticalItem.DRAGONSTONE, ActivitySecondaries.GOLD_BAR),
ONYX_RING(ItemID.ONYX_RING, "Onyx ring", Skill.CRAFTING, 67, 115, CriticalItem.ONYX, ActivitySecondaries.GOLD_BAR),
ONYX_NECKLACE(ItemID.ONYX_NECKLACE, "Onyx necklace", Skill.CRAFTING, 82, 120, CriticalItem.ONYX, ActivitySecondaries.GOLD_BAR),
REGEN_BRACELET(ItemID.REGEN_BRACELET, "Regen bracelet", Skill.CRAFTING, 84, 125, CriticalItem.ONYX, ActivitySecondaries.GOLD_BAR),
ONYX_AMULET(ItemID.ONYX_AMULET, "Onyx amulet", Skill.CRAFTING, 90, 165, CriticalItem.ONYX, ActivitySecondaries.GOLD_BAR),
ZENYTE_RING(ItemID.ZENYTE_RING, "Zenyte ring", Skill.CRAFTING, 89, 150, CriticalItem.ZENYTE, ActivitySecondaries.GOLD_BAR),
ZENYTE_NECKLACE(ItemID.ZENYTE_NECKLACE, "Zenyte necklace", Skill.CRAFTING, 92, 165, CriticalItem.ZENYTE, ActivitySecondaries.GOLD_BAR),
ZENYTE_BRACELET(ItemID.ZENYTE_BRACELET, "Zenyte bracelet", Skill.CRAFTING, 95, 180, CriticalItem.ZENYTE, ActivitySecondaries.GOLD_BAR),
ZENYTE_AMULET(ItemID.ZENYTE_AMULET, "Zenyte amulet", Skill.CRAFTING, 98, 200, CriticalItem.ZENYTE, ActivitySecondaries.GOLD_BAR),
SAPPHIRE_RING(ItemID.SAPPHIRE_RING, "Sapphire ring", Skill.CRAFTING, 20, 40,
CriticalItem.SAPPHIRE, Secondaries.GOLD_BAR, new ItemStack(ItemID.SAPPHIRE_RING, 1)),
SAPPHIRE_NECKLACE(ItemID.SAPPHIRE_NECKLACE, "Sapphire necklace", Skill.CRAFTING, 22, 55,
CriticalItem.SAPPHIRE, Secondaries.GOLD_BAR, new ItemStack(ItemID.SAPPHIRE_NECKLACE, 1)),
SAPPHIRE_BRACELET(ItemID.SAPPHIRE_BRACELET, "Sapphire bracelet", Skill.CRAFTING, 23, 60,
CriticalItem.SAPPHIRE, Secondaries.GOLD_BAR, new ItemStack(ItemID.SAPPHIRE_BRACELET, 1)),
SAPPHIRE_AMULET(ItemID.SAPPHIRE_AMULET, "Sapphire amulet", Skill.CRAFTING, 24, 65,
CriticalItem.SAPPHIRE, Secondaries.GOLD_BAR, new ItemStack(ItemID.SAPPHIRE_AMULET, 1)),
EMERALD_RING(ItemID.EMERALD_RING, "Emerald ring", Skill.CRAFTING, 27, 55,
CriticalItem.EMERALD, Secondaries.GOLD_BAR, new ItemStack(ItemID.EMERALD_RING, 1)),
EMERALD_NECKLACE(ItemID.EMERALD_NECKLACE, "Emerald necklace", Skill.CRAFTING, 29, 60,
CriticalItem.EMERALD, Secondaries.GOLD_BAR, new ItemStack(ItemID.EMERALD_NECKLACE, 1)),
EMERALD_BRACELET(ItemID.EMERALD_BRACELET, "Emerald bracelet", Skill.CRAFTING, 30, 65,
CriticalItem.EMERALD, Secondaries.GOLD_BAR, new ItemStack(ItemID.EMERALD_BRACELET, 1)),
EMERALD_AMULET(ItemID.EMERALD_AMULET, "Emerald amulet", Skill.CRAFTING, 31, 70,
CriticalItem.EMERALD, Secondaries.GOLD_BAR, new ItemStack(ItemID.EMERALD_AMULET, 1)),
RUBY_RING(ItemID.RUBY_RING, "Ruby ring", Skill.CRAFTING, 34, 70,
CriticalItem.RUBY, Secondaries.GOLD_BAR, new ItemStack(ItemID.RUBY_RING, 1)),
RUBY_NECKLACE(ItemID.RUBY_NECKLACE, "Ruby necklace", Skill.CRAFTING, 40, 75,
CriticalItem.RUBY, Secondaries.GOLD_BAR, new ItemStack(ItemID.RUBY_NECKLACE, 1)),
RUBY_BRACELET(ItemID.RUBY_BRACELET, "Ruby bracelet", Skill.CRAFTING, 42, 80,
CriticalItem.RUBY, Secondaries.GOLD_BAR, new ItemStack(ItemID.RUBY_BRACELET, 1)),
RUBY_AMULET(ItemID.RUBY_AMULET, "Ruby amulet", Skill.CRAFTING, 50, 85,
CriticalItem.RUBY, Secondaries.GOLD_BAR, new ItemStack(ItemID.RUBY_AMULET, 1)),
DIAMOND_RING(ItemID.DIAMOND_RING, "Diamond ring", Skill.CRAFTING, 43, 85,
CriticalItem.DIAMOND, Secondaries.GOLD_BAR, new ItemStack(ItemID.DIAMOND_RING, 1)),
DIAMOND_NECKLACE(ItemID.DIAMOND_NECKLACE, "Diamond necklace", Skill.CRAFTING, 56, 90,
CriticalItem.DIAMOND, Secondaries.GOLD_BAR, new ItemStack(ItemID.DIAMOND_NECKLACE, 1)),
DIAMOND_BRACELET(ItemID.DIAMOND_BRACELET, "Diamond bracelet", Skill.CRAFTING, 58, 95,
CriticalItem.DIAMOND, Secondaries.GOLD_BAR, new ItemStack(ItemID.DIAMOND_BRACELET, 1)),
DIAMOND_AMULET(ItemID.DIAMOND_AMULET, "Diamond amulet", Skill.CRAFTING, 70, 100,
CriticalItem.DIAMOND, Secondaries.GOLD_BAR, new ItemStack(ItemID.DIAMOND_AMULET, 1)),
DRAGONSTONE_RING(ItemID.DRAGONSTONE_RING, "Dragonstone ring", Skill.CRAFTING, 55, 100,
CriticalItem.DRAGONSTONE, Secondaries.GOLD_BAR, new ItemStack(ItemID.DRAGONSTONE_RING, 1)),
DRAGON_NECKLACE(ItemID.DRAGON_NECKLACE, "Dragon necklace", Skill.CRAFTING, 72, 105,
CriticalItem.DRAGONSTONE, Secondaries.GOLD_BAR, new ItemStack(ItemID.DRAGON_NECKLACE, 1)),
DRAGONSTONE_BRACELET(ItemID.DRAGONSTONE_BRACELET, "Dragonstone bracelet", Skill.CRAFTING, 74, 110,
CriticalItem.DRAGONSTONE, Secondaries.GOLD_BAR, new ItemStack(ItemID.DRAGONSTONE_BRACELET, 1)),
DRAGONSTONE_AMULET(ItemID.DRAGONSTONE_AMULET, "Dragonstone amulet", Skill.CRAFTING, 80, 150,
CriticalItem.DRAGONSTONE, Secondaries.GOLD_BAR, new ItemStack(ItemID.DRAGONSTONE_AMULET, 1)),
ONYX_RING(ItemID.ONYX_RING, "Onyx ring", Skill.CRAFTING, 67, 115,
CriticalItem.ONYX, Secondaries.GOLD_BAR, new ItemStack(ItemID.ONYX_RING, 1)),
ONYX_NECKLACE(ItemID.ONYX_NECKLACE, "Onyx necklace", Skill.CRAFTING, 82, 120,
CriticalItem.ONYX, Secondaries.GOLD_BAR, new ItemStack(ItemID.ONYX_NECKLACE, 1)),
REGEN_BRACELET(ItemID.REGEN_BRACELET, "Regen bracelet", Skill.CRAFTING, 84, 125,
CriticalItem.ONYX, Secondaries.GOLD_BAR, new ItemStack(ItemID.REGEN_BRACELET, 1)),
ONYX_AMULET(ItemID.ONYX_AMULET, "Onyx amulet", Skill.CRAFTING, 90, 165,
CriticalItem.ONYX, Secondaries.GOLD_BAR, new ItemStack(ItemID.ONYX_AMULET, 1)),
ZENYTE_RING(ItemID.ZENYTE_RING, "Zenyte ring", Skill.CRAFTING, 89, 150,
CriticalItem.ZENYTE, Secondaries.GOLD_BAR, new ItemStack(ItemID.ZENYTE_RING, 1)),
ZENYTE_NECKLACE(ItemID.ZENYTE_NECKLACE, "Zenyte necklace", Skill.CRAFTING, 92, 165,
CriticalItem.ZENYTE, Secondaries.GOLD_BAR, new ItemStack(ItemID.ZENYTE_NECKLACE, 1)),
ZENYTE_BRACELET(ItemID.ZENYTE_BRACELET, "Zenyte bracelet", Skill.CRAFTING, 95, 180,
CriticalItem.ZENYTE, Secondaries.GOLD_BAR, new ItemStack(ItemID.ZENYTE_BRACELET, 1)),
ZENYTE_AMULET(ItemID.ZENYTE_AMULET, "Zenyte amulet", Skill.CRAFTING, 98, 200,
CriticalItem.ZENYTE, Secondaries.GOLD_BAR, new ItemStack(ItemID.ZENYTE_AMULET, 1)),
// Battle Staves
WATER_BATTLESTAFF(ItemID.WATER_BATTLESTAFF, "Water battlestaff", Skill.CRAFTING, 54, 100, CriticalItem.BATTLESTAFF, ActivitySecondaries.WATER_ORB),
EARTH_BATTLESTAFF(ItemID.EARTH_BATTLESTAFF, "Earth battlestaff", Skill.CRAFTING, 58, 112.5, CriticalItem.BATTLESTAFF, ActivitySecondaries.EARTH_ORB),
FIRE_BATTLESTAFF(ItemID.FIRE_BATTLESTAFF, "Fire battlestaff", Skill.CRAFTING, 62, 125, CriticalItem.BATTLESTAFF, ActivitySecondaries.FIRE_ORB),
AIR_BATTLESTAFF(ItemID.AIR_BATTLESTAFF, "Air battlestaff", Skill.CRAFTING, 66, 137.5, CriticalItem.BATTLESTAFF, ActivitySecondaries.AIR_ORB),
WATER_BATTLESTAFF(ItemID.WATER_BATTLESTAFF, "Water battlestaff", Skill.CRAFTING, 54, 100,
CriticalItem.BATTLESTAFF, Secondaries.WATER_ORB, new ItemStack(ItemID.WATER_BATTLESTAFF, 1)),
EARTH_BATTLESTAFF(ItemID.EARTH_BATTLESTAFF, "Earth battlestaff", Skill.CRAFTING, 58, 112.5,
CriticalItem.BATTLESTAFF, Secondaries.EARTH_ORB, new ItemStack(ItemID.EARTH_BATTLESTAFF, 1)),
FIRE_BATTLESTAFF(ItemID.FIRE_BATTLESTAFF, "Fire battlestaff", Skill.CRAFTING, 62, 125,
CriticalItem.BATTLESTAFF, Secondaries.FIRE_ORB, new ItemStack(ItemID.FIRE_BATTLESTAFF, 1)),
AIR_BATTLESTAFF(ItemID.AIR_BATTLESTAFF, "Air battlestaff", Skill.CRAFTING, 66, 137.5,
CriticalItem.BATTLESTAFF, Secondaries.AIR_ORB, new ItemStack(ItemID.AIR_BATTLESTAFF, 1)),
/*
* Smithing Items
*/
// Smelting ores (Furnace)
IRON_ORE(ItemID.IRON_BAR, "Iron Bars", Skill.SMITHING, 15, 12.5, CriticalItem.IRON_ORE, ActivitySecondaries.COAL_ORE),
STEEL_ORE(ItemID.STEEL_BAR, "Steel Bars", Skill.SMITHING, 30, 17.5, CriticalItem.IRON_ORE, ActivitySecondaries.COAL_ORE_2),
SILVER_ORE(ItemID.SILVER_ORE, "Bar", Skill.SMITHING, 20, 13.67, CriticalItem.SILVER_ORE),
GOLD_ORE(ItemID.GOLD_BAR, "Regular exp", Skill.SMITHING, 40, 22.5, CriticalItem.GOLD_ORE),
GOLD_ORE_GAUNTLETS(ItemID.GOLDSMITH_GAUNTLETS, "Goldsmith Gauntlets", Skill.SMITHING, 40, 56.2, CriticalItem.GOLD_ORE),
MITHRIL_ORE(ItemID.MITHRIL_ORE, "Bar", Skill.SMITHING, 50, 30, CriticalItem.MITHRIL_ORE, ActivitySecondaries.COAL_ORE_4),
ADAMANTITE_ORE(ItemID.ADAMANTITE_ORE, "Bar", Skill.SMITHING, 70, 37.5, CriticalItem.ADAMANTITE_ORE, ActivitySecondaries.COAL_ORE_6),
RUNITE_ORE(ItemID.RUNITE_ORE, "Bar", Skill.SMITHING, 85, 50, CriticalItem.RUNITE_ORE, ActivitySecondaries.COAL_ORE_8),
IRON_ORE(ItemID.IRON_BAR, "Iron bar", Skill.SMITHING, 15, 12.5,
CriticalItem.IRON_ORE, Secondaries.COAL_ORE, new ItemStack(ItemID.IRON_BAR, 1)),
STEEL_ORE(ItemID.STEEL_BAR, "Steel bar", Skill.SMITHING, 30, 17.5,
CriticalItem.IRON_ORE, Secondaries.COAL_ORE_2, new ItemStack(ItemID.STEEL_BAR, 1)),
SILVER_ORE(ItemID.SILVER_BAR, "Silver Bar", Skill.SMITHING, 20, 13.67,
CriticalItem.SILVER_ORE, null, new ItemStack(ItemID.SILVER_BAR, 1)),
GOLD_ORE(ItemID.GOLD_BAR, "Gold bar", Skill.SMITHING, 40, 22.5,
CriticalItem.GOLD_ORE, null, new ItemStack(ItemID.GOLD_BAR, 1)),
GOLD_ORE_GAUNTLETS(ItemID.GOLDSMITH_GAUNTLETS, "Goldsmith gauntlets", Skill.SMITHING, 40, 56.2,
CriticalItem.GOLD_ORE, null, new ItemStack(ItemID.GOLD_BAR, 1)),
MITHRIL_ORE(ItemID.MITHRIL_BAR, "Mithril bar", Skill.SMITHING, 50, 30,
CriticalItem.MITHRIL_ORE, Secondaries.COAL_ORE_4, new ItemStack(ItemID.MITHRIL_BAR, 1)),
ADAMANTITE_ORE(ItemID.ADAMANTITE_BAR, "Adamantite bar", Skill.SMITHING, 70, 37.5,
CriticalItem.ADAMANTITE_ORE, Secondaries.COAL_ORE_6, new ItemStack(ItemID.ADAMANTITE_BAR, 1)),
RUNITE_ORE(ItemID.RUNITE_BAR, "Runite bar", Skill.SMITHING, 85, 50,
CriticalItem.RUNITE_ORE, Secondaries.COAL_ORE_8, new ItemStack(ItemID.RUNITE_BAR, 1)),
// Smelting bars (Anvil)
BRONZE_BAR(ItemID.BRONZE_BAR, "Bars", Skill.SMITHING, 1, 12.5, CriticalItem.BRONZE_BAR),
IRON_BAR(ItemID.IRON_BAR, "Bars", Skill.SMITHING, 15, 25.0, CriticalItem.IRON_BAR),
STEEL_BAR(ItemID.STEEL_BAR, "Steel Products", Skill.SMITHING, 30, 37.5, CriticalItem.STEEL_BAR),
CANNONBALLS(ItemID.CANNONBALL, "Cannonballs", Skill.SMITHING, 35, 25.5, CriticalItem.STEEL_BAR),
MITHRIL_BAR(ItemID.MITHRIL_BAR, "Bars", Skill.SMITHING, 50, 50.0, CriticalItem.MITHRIL_BAR),
ADAMANTITE_BAR(ItemID.ADAMANTITE_BAR, "Bars", Skill.SMITHING, 70, 62.5, CriticalItem.ADAMANTITE_BAR),
RUNITE_BAR(ItemID.RUNITE_BAR, "Bars", Skill.SMITHING, 85, 75.0, CriticalItem.RUNITE_BAR),
BRONZE_BAR(ItemID.BRONZE_BAR, "Bronze products", Skill.SMITHING, 1, 12.5,
CriticalItem.BRONZE_BAR, null, null),
IRON_BAR(ItemID.IRON_BAR, "Iron products", Skill.SMITHING, 15, 25.0,
CriticalItem.IRON_BAR, null, null),
STEEL_BAR(ItemID.STEEL_BAR, "Steel products", Skill.SMITHING, 30, 37.5,
CriticalItem.STEEL_BAR, null, null),
CANNONBALLS(ItemID.CANNONBALL, "Cannonballs", Skill.SMITHING, 35, 25.5,
CriticalItem.STEEL_BAR, null, new ItemStack(ItemID.CANNONBALL, 4)),
MITHRIL_BAR(ItemID.MITHRIL_BAR, "Mithril products", Skill.SMITHING, 50, 50.0,
CriticalItem.MITHRIL_BAR, null, null),
ADAMANTITE_BAR(ItemID.ADAMANTITE_BAR, "Adamantite products", Skill.SMITHING, 70, 62.5,
CriticalItem.ADAMANTITE_BAR, null, null),
RUNITE_BAR(ItemID.RUNITE_BAR, "Runite products", Skill.SMITHING, 85, 75.0,
CriticalItem.RUNITE_BAR, null, null),
/**
* Farming Items
*/
ACORN(ItemID.ACORN, "Seeds", Skill.FARMING, 15, 481.3, CriticalItem.ACORN),
WILLOW_SEED(ItemID.WILLOW_SEED, "Seeds", Skill.FARMING, 30, 1481.5, CriticalItem.WILLOW_SEED),
MAPLE_SEED(ItemID.MAPLE_SEED, "Seeds", Skill.FARMING, 45, 3448.4, CriticalItem.MAPLE_SEED),
YEW_SEED(ItemID.YEW_SEED, "Seeds", Skill.FARMING, 60, 7150.9, CriticalItem.YEW_SEED),
MAGIC_SEED(ItemID.MAGIC_SEED, "Seeds", Skill.FARMING, 75, 13913.8, CriticalItem.MAGIC_SEED),
APPLE_TREE_SEED(ItemID.APPLE_TREE_SEED, "Seeds", Skill.FARMING, 27, 1272.5, CriticalItem.APPLE_TREE_SEED),
BANANA_TREE_SEED(ItemID.BANANA_TREE_SEED, "Seeds", Skill.FARMING, 33, 1841.5, CriticalItem.BANANA_TREE_SEED),
ORANGE_TREE_SEED(ItemID.ORANGE_TREE_SEED, "Seeds", Skill.FARMING, 39, 2586.7, CriticalItem.ORANGE_TREE_SEED),
CURRY_TREE_SEED(ItemID.CURRY_TREE_SEED, "Seeds", Skill.FARMING, 42, 3036.9, CriticalItem.CURRY_TREE_SEED),
PINEAPPLE_SEED(ItemID.PINEAPPLE_SEED, "Seeds", Skill.FARMING, 51, 4791.7, CriticalItem.PINEAPPLE_SEED),
PAPAYA_TREE_SEED(ItemID.PAPAYA_TREE_SEED, "Seeds", Skill.FARMING, 57, 6380.4, CriticalItem.PAPAYA_TREE_SEED),
PALM_TREE_SEED(ItemID.PALM_TREE_SEED, "Seeds", Skill.FARMING, 68, 10509.6, CriticalItem.PALM_TREE_SEED),
CALQUAT_TREE_SEED(ItemID.CALQUAT_TREE_SEED, "Seeds", Skill.FARMING, 72, 12516.5, CriticalItem.CALQUAT_TREE_SEED),
TEAK_SEED(ItemID.TEAK_SEED, "Seeds", Skill.FARMING, 35, 7325, CriticalItem.TEAK_SEED),
MAHOGANY_SEED(ItemID.MAHOGANY_SEED, "Seeds", Skill.FARMING, 55, 15783, CriticalItem.MAHOGANY_SEED),
SPIRIT_SEED(ItemID.SPIRIT_SEED, "Seeds", Skill.FARMING, 83, 19500, CriticalItem.SPIRIT_SEED),
ACORN(ItemID.OAK_SAPLING, "Oak sapling", Skill.FARMING, 15, 0,
CriticalItem.ACORN, null, new ItemStack(ItemID.OAK_SAPLING, 1)),
WILLOW_SEED(ItemID.WILLOW_SAPLING, "Willow sapling", Skill.FARMING, 30, 0,
CriticalItem.WILLOW_SEED, null, new ItemStack(ItemID.WILLOW_SAPLING, 1)),
MAPLE_SEED(ItemID.MAPLE_SAPLING, "Maple sapling", Skill.FARMING, 45, 0,
CriticalItem.MAPLE_SEED, null, new ItemStack(ItemID.MAPLE_SAPLING, 1)),
YEW_SEED(ItemID.YEW_SAPLING, "Yew sapling", Skill.FARMING, 60, 0,
CriticalItem.YEW_SEED, null, new ItemStack(ItemID.YEW_SAPLING, 1)),
MAGIC_SEED(ItemID.MAGIC_SAPLING, "Magic sapling", Skill.FARMING, 75, 0,
CriticalItem.MAGIC_SEED, null, new ItemStack(ItemID.MAGIC_SAPLING, 1)),
APPLE_TREE_SEED(ItemID.APPLE_SAPLING, "Apple sapling", Skill.FARMING, 27, 0,
CriticalItem.APPLE_TREE_SEED, null, new ItemStack(ItemID.APPLE_SAPLING, 1)),
BANANA_TREE_SEED(ItemID.BANANA_SAPLING, "Banana sapling", Skill.FARMING, 33, 0,
CriticalItem.BANANA_TREE_SEED, null, new ItemStack(ItemID.BANANA_SAPLING, 1)),
ORANGE_TREE_SEED(ItemID.ORANGE_SAPLING, "Orange sapling", Skill.FARMING, 39, 0,
CriticalItem.ORANGE_TREE_SEED, null, new ItemStack(ItemID.ORANGE_SAPLING, 1)),
CURRY_TREE_SEED(ItemID.CURRY_SAPLING, "Curry sapling", Skill.FARMING, 42, 0,
CriticalItem.CURRY_TREE_SEED, null, new ItemStack(ItemID.CURRY_SAPLING, 1)),
PINEAPPLE_SEED(ItemID.PINEAPPLE_SAPLING, "Pineapple sapling", Skill.FARMING, 51, 0,
CriticalItem.PINEAPPLE_SEED, null, new ItemStack(ItemID.PINEAPPLE_SAPLING, 1)),
PAPAYA_TREE_SEED(ItemID.PAPAYA_SAPLING, "Papaya sapling", Skill.FARMING, 57, 0,
CriticalItem.PAPAYA_TREE_SEED, null, new ItemStack(ItemID.PAPAYA_SAPLING, 1)),
PALM_TREE_SEED(ItemID.PALM_SAPLING, "Palm sapling", Skill.FARMING, 68, 0,
CriticalItem.PALM_TREE_SEED, null, new ItemStack(ItemID.PALM_SAPLING, 1)),
CALQUAT_TREE_SEED(ItemID.CALQUAT_SAPLING, "Calquat sapling", Skill.FARMING, 72, 0,
CriticalItem.CALQUAT_TREE_SEED, null, new ItemStack(ItemID.CALQUAT_SAPLING, 1)),
TEAK_SEED(ItemID.TEAK_SAPLING, "Teak sapling", Skill.FARMING, 35, 0,
CriticalItem.TEAK_SEED, null, new ItemStack(ItemID.TEAK_SAPLING, 1)),
MAHOGANY_SEED(ItemID.MAHOGANY_SAPLING, "Mahogany sapling", Skill.FARMING, 55, 0,
CriticalItem.MAHOGANY_SEED, null, new ItemStack(ItemID.MAHOGANY_SAPLING, 1)),
SPIRIT_SEED(ItemID.SPIRIT_SAPLING, "Spirit sapling", Skill.FARMING, 83, 0,
CriticalItem.SPIRIT_SEED, null, new ItemStack(ItemID.SPIRIT_SAPLING, 1)),
OAK_SAPPLING(ItemID.OAK_SAPLING, "Oak tree", Skill.FARMING, 15, 481.3,
CriticalItem.OAK_SAPLING, null, null),
WILLOW_SAPLING(ItemID.WILLOW_SAPLING, "Willow tree", Skill.FARMING, 30, 1481.5,
CriticalItem.WILLOW_SAPLING, null, null),
MAPLE_SAPLING(ItemID.MAPLE_SAPLING, "Maple tree", Skill.FARMING, 45, 3448.4,
CriticalItem.MAPLE_SAPLING, null, null),
YEW_SAPLING(ItemID.YEW_SAPLING, "Yew tree", Skill.FARMING, 60, 7150.9,
CriticalItem.YEW_SAPLING, null, null),
MAGIC_SAPLING(ItemID.MAGIC_SAPLING, "Magic tree", Skill.FARMING, 75, 13913.8,
CriticalItem.MAGIC_SAPLING, null, null),
APPLE_TREE_SAPLING(ItemID.APPLE_SAPLING, "Apple tree", Skill.FARMING, 27, 1272.5,
CriticalItem.APPLE_TREE_SAPLING, null, null),
BANANA_TREE_SAPLING(ItemID.BANANA_SAPLING, "Banana tree", Skill.FARMING, 33, 1841.5,
CriticalItem.BANANA_TREE_SAPLING, null, null),
ORANGE_TREE_SAPLING(ItemID.ORANGE_SAPLING, "Orange tree", Skill.FARMING, 39, 2586.7,
CriticalItem.ORANGE_TREE_SAPLING, null, null),
CURRY_TREE_SAPLING(ItemID.CURRY_SAPLING, "Curry tree", Skill.FARMING, 42, 3036.9,
CriticalItem.CURRY_TREE_SAPLING, null, null),
PINEAPPLE_SAPLING(ItemID.PINEAPPLE_SAPLING, "Pineapple tree", Skill.FARMING, 51, 4791.7,
CriticalItem.PINEAPPLE_SAPLING, null, null),
PAPAYA_TREE_SAPLING(ItemID.PAPAYA_SAPLING, "Papaya tree", Skill.FARMING, 57, 6380.4,
CriticalItem.PAPAYA_TREE_SAPLING, null, null),
PALM_TREE_SAPLING(ItemID.PALM_SAPLING, "Palm tree", Skill.FARMING, 68, 10509.6,
CriticalItem.PALM_TREE_SAPLING, null, null),
CALQUAT_TREE_SAPLING(ItemID.CALQUAT_SAPLING, "Calquat tree", Skill.FARMING, 72, 12516.5,
CriticalItem.CALQUAT_TREE_SAPLING, null, null),
TEAK_SAPLING(ItemID.TEAK_SAPLING, "Teak tree", Skill.FARMING, 35, 7325,
CriticalItem.TEAK_SAPLING, null, null),
MAHOGANY_SAPLING(ItemID.MAHOGANY_SAPLING, "Mahogany tree", Skill.FARMING, 55, 15783,
CriticalItem.MAHOGANY_SAPLING, null, null),
SPIRIT_SAPLING(ItemID.SPIRIT_SAPLING, "Spirit tree", Skill.FARMING, 83, 19500,
CriticalItem.SPIRIT_SAPLING, null, null),
;
private final int icon;
private final String name;
private final CriticalItem criticalItem;
private final Skill skill;
private final int level;
private final double xp;
private final SecondaryItem[] secondaries;
private final CriticalItem criticalItem;
private final boolean preventLinked;
private final ItemStack[] secondaries;
@Nullable
private final ItemStack output;
private ItemInfo outputItemInfo = null;
@Nullable
private final CriticalItem linkedItem;
Activity(int Icon, String name, Skill skill, int level, double xp, CriticalItem criticalItem)
{
this.icon = Icon;
this.name = name;
this.skill = skill;
this.level = level;
this.xp = xp;
this.criticalItem = criticalItem;
this.secondaries = new SecondaryItem[0];
this.preventLinked = false;
}
// Store activity by CriticalItem
private static final ImmutableMultimap<CriticalItem, Activity> CRITICAL_MAP;
Activity(int Icon, String name, Skill skill, int level, double xp, CriticalItem criticalItem, ActivitySecondaries secondaries)
static
{
this.icon = Icon;
this.name = name;
this.skill = skill;
this.level = level;
this.xp = xp;
this.criticalItem = criticalItem;
this.secondaries = secondaries == null ? new SecondaryItem[0] : secondaries.getItems();
this.preventLinked = false;
}
Activity(final int Icon, final String name, final Skill skill, final int level, final double xp, final CriticalItem criticalItem, final ActivitySecondaries secondaries, final boolean preventLinked)
{
this.icon = Icon;
this.name = name;
this.skill = skill;
this.level = level;
this.xp = xp;
this.criticalItem = criticalItem;
this.secondaries = secondaries == null ? new SecondaryItem[0] : secondaries.getItems();
this.preventLinked = preventLinked;
}
// Builds a Map to reduce looping frequency
private static Map<CriticalItem, ArrayList<Activity>> buildItemMap()
{
Map<CriticalItem, ArrayList<Activity>> map = new HashMap<>();
for (Activity item : values())
final ImmutableMultimap.Builder<CriticalItem, Activity> map = ImmutableMultimap.builder();
for (final Activity item : values())
{
map.computeIfAbsent(item.getCriticalItem(), e -> new ArrayList<>()).add(item);
map.put(item.getCriticalItem(), item);
}
return map;
CRITICAL_MAP = map.build();
}
private static final Map<CriticalItem, ArrayList<Activity>> byCriticalItem = buildItemMap();
public static List<Activity> getByCriticalItem(CriticalItem item)
Activity(
final int icon,
final String name,
final Skill skill,
final int level,
final double xp,
final CriticalItem criticalItem,
@Nullable final Secondaries secondaries,
@Nullable final ItemStack output)
{
return byCriticalItem.getOrDefault(item, new ArrayList<>());
this.icon = icon;
this.name = name;
this.skill = skill;
this.level = level;
this.xp = xp;
this.criticalItem = criticalItem;
this.secondaries = secondaries == null ? new ItemStack[0] : secondaries.getItems();
this.output = output;
this.linkedItem = output == null ? null : CriticalItem.getByItemId(output.getId());
}
/**
* Get all Activities for this CriticalItem
*
* @param item CriticalItem to check for
* @param limitLevel Level to check Activitiy requirements against. -1 or 0 value disables limits
* @return an empty list if no activities
* @param item CriticalItem to check for
* @return an empty Collection if no activities
*/
public static List<Activity> getByCriticalItem(CriticalItem item, int limitLevel)
public static List<Activity> getByCriticalItem(CriticalItem item)
{
List<Activity> activities = getByCriticalItem(item);
List<Activity> l = new ArrayList<>();
final Collection<Activity> activities = CRITICAL_MAP.get(item);
if (activities == null)
{
return new ArrayList<>();
}
return new ArrayList<>(activities);
}
/**
* Get all Activities for this CriticalItem limited to level
*
* @param item CriticalItem to check for
* @param limitLevel Level to check Activitiy requirements against. -1/0 value disables limits
* @return an empty Collection if no activities
*/
public static List<Activity> getByCriticalItem(final CriticalItem item, final int limitLevel)
{
// Return as list to allow getting by index
final List<Activity> l = getByCriticalItem(item);
if (limitLevel <= 0)
{
return l;
}
for (Activity a : activities)
{
if (!(a.getLevel() > limitLevel))
{
l.add(a);
}
}
return l;
return l.stream().filter(a -> a.getLevel() <= limitLevel).collect(Collectors.toList());
}
}
/**
* Attaches the Item Composition to each CriticalItem on client initial load
*
* @param m ItemManager
*/
public static void prepareItemDefinitions(ItemManager m)
{
for (Activity a : values())
{
final ItemStack output = a.getOutput();
if (output == null)
{
continue;
}
if (a.getOutputItemInfo() != null)
{
return;
}
final ItemDefinition c = m.getItemDefinition(output.getId());
a.outputItemInfo = new ItemInfo(c.getName(), c.isStackable());
}
}
}

View File

@@ -1,112 +0,0 @@
/*
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.skillcalculator.banked.beans;
import lombok.AccessLevel;
import lombok.Getter;
import net.runelite.api.ItemID;
@Getter(AccessLevel.PUBLIC)
public enum ActivitySecondaries
{
/**
* Herblore
*/
UNFINISHED_POTION(new SecondaryItem(ItemID.VIAL_OF_WATER, 1)),
SWAMP_TAR(new SecondaryItem(ItemID.SWAMP_TAR, 15)),
// Guam
ATTACK_POTION(new SecondaryItem(ItemID.EYE_OF_NEWT)),
// Marrentil
ANTIPOISON(new SecondaryItem(ItemID.UNICORN_HORN_DUST)),
// Tarromin
STRENGTH_POTION(new SecondaryItem(ItemID.LIMPWURT_ROOT)),
SERUM_207(new SecondaryItem(ItemID.ASHES)),
// Harralander
COMPOST_POTION(new SecondaryItem(ItemID.VOLCANIC_ASH)),
RESTORE_POTION(new SecondaryItem(ItemID.RED_SPIDERS_EGGS)),
ENERGY_POTION(new SecondaryItem(ItemID.CHOCOLATE_DUST)),
COMBAT_POTION(new SecondaryItem(ItemID.GOAT_HORN_DUST)),
// Ranarr Weed
DEFENCE_POTION(new SecondaryItem(ItemID.WHITE_BERRIES)),
PRAYER_POTION(new SecondaryItem(ItemID.SNAPE_GRASS)),
// Toadflax
AGILITY_POTION(new SecondaryItem(ItemID.TOADS_LEGS)),
SARADOMIN_BREW(new SecondaryItem(ItemID.CRUSHED_NEST)),
// Irit
SUPER_ATTACK(new SecondaryItem(ItemID.EYE_OF_NEWT)),
SUPERANTIPOISON(new SecondaryItem(ItemID.UNICORN_HORN_DUST)),
// Avantoe
FISHING_POTION(new SecondaryItem(ItemID.SNAPE_GRASS)),
SUPER_ENERGY_POTION(new SecondaryItem(ItemID.MORT_MYRE_FUNGUS)),
HUNTER_POTION(new SecondaryItem(ItemID.KEBBIT_TEETH_DUST)),
// Kwuarm
SUPER_STRENGTH(new SecondaryItem(ItemID.LIMPWURT_ROOT)),
// Snapdragon
SUPER_RESTORE(new SecondaryItem(ItemID.RED_SPIDERS_EGGS)),
SANFEW_SERUM(new SecondaryItem(ItemID.SNAKE_WEED), new SecondaryItem(ItemID.UNICORN_HORN_DUST), new SecondaryItem(ItemID.SUPER_RESTORE4), new SecondaryItem(ItemID.NAIL_BEAST_NAILS)),
// Cadantine
SUPER_DEFENCE_POTION(new SecondaryItem(ItemID.WHITE_BERRIES)),
// Lantadyme
ANTIFIRE_POTION(new SecondaryItem(ItemID.DRAGON_SCALE_DUST)),
MAGIC_POTION(new SecondaryItem(ItemID.POTATO_CACTUS)),
// Dwarf Weed
RANGING_POTION(new SecondaryItem(ItemID.WINE_OF_ZAMORAK)),
// Torstol
ZAMORAK_BREW(new SecondaryItem(ItemID.JANGERBERRIES)),
SUPER_COMBAT_POTION(new SecondaryItem(ItemID.SUPER_ATTACK3), new SecondaryItem(ItemID.SUPER_STRENGTH3), new SecondaryItem(ItemID.SUPER_DEFENCE3)),
ANTIVENOM_PLUS(new SecondaryItem(ItemID.ANTIVENOM4)),
/**
* Smithing
*/
COAL_ORE(new SecondaryItem(ItemID.COAL)),
COAL_ORE_2(new SecondaryItem(ItemID.COAL, 2)),
COAL_ORE_4(new SecondaryItem(ItemID.COAL, 4)),
COAL_ORE_6(new SecondaryItem(ItemID.COAL, 6)),
COAL_ORE_8(new SecondaryItem(ItemID.COAL, 8)),
/**
* Crafting
*/
GOLD_BAR(new SecondaryItem(ItemID.GOLD_BAR)),
SILVER_BAR(new SecondaryItem(ItemID.SILVER_BAR)),
WATER_ORB(new SecondaryItem(ItemID.WATER_ORB)),
EARTH_ORB(new SecondaryItem(ItemID.EARTH_ORB)),
FIRE_ORB(new SecondaryItem(ItemID.FIRE_ORB)),
AIR_ORB(new SecondaryItem(ItemID.AIR_ORB)),
/**
* Cooking
*/
JUG_OF_WATER(new SecondaryItem(ItemID.JUG_OF_WATER)),
;
private final SecondaryItem[] items;
ActivitySecondaries(final SecondaryItem... items)
{
this.items = items;
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.skillcalculator.banked.beans;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public class BankedItem
{
private final CriticalItem item;
private final int qty;
public double getXpRate()
{
final Activity selectedActivity = item.getSelectedActivity();
if (selectedActivity == null)
{
return 0;
}
return selectedActivity.getXp();
}
@Override
public String toString()
{
return item.name() + " x " + qty;
}
}

View File

@@ -0,0 +1,355 @@
/*
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.skillcalculator.banked.beans;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import lombok.Getter;
import lombok.Setter;
import net.runelite.api.ItemDefinition;
import net.runelite.api.ItemID;
import net.runelite.api.Skill;
import net.runelite.client.game.ItemManager;
@Getter
public enum CriticalItem
{
/**
* Construction Items
*/
// Logs
LOGS(ItemID.LOGS, Skill.CONSTRUCTION, "Logs"),
OAK_LOGS(ItemID.OAK_LOGS, Skill.CONSTRUCTION, "Logs"),
TEAK_LOGS(ItemID.TEAK_LOGS, Skill.CONSTRUCTION, "Logs"),
MAHOGANY_LOGS(ItemID.MAHOGANY_LOGS, Skill.CONSTRUCTION, "Logs"),
// Planks
PLANK(ItemID.PLANK, Skill.CONSTRUCTION, "Planks"),
OAK_PLANK(ItemID.OAK_PLANK, Skill.CONSTRUCTION, "Planks"),
TEAK_PLANK(ItemID.TEAK_PLANK, Skill.CONSTRUCTION, "Planks"),
MAHOGANY_PLANK(ItemID.MAHOGANY_PLANK, Skill.CONSTRUCTION, "Planks"),
/**
* Herblore Items
*/
// Grimy Herbs
GRIMY_GUAM_LEAF(ItemID.GRIMY_GUAM_LEAF, Skill.HERBLORE, "Grimy Herbs"),
GRIMY_MARRENTILL(ItemID.GRIMY_MARRENTILL, Skill.HERBLORE, "Grimy Herbs"),
GRIMY_TARROMIN(ItemID.GRIMY_TARROMIN, Skill.HERBLORE, "Grimy Herbs"),
GRIMY_HARRALANDER(ItemID.GRIMY_HARRALANDER, Skill.HERBLORE, "Grimy Herbs"),
GRIMY_RANARR_WEED(ItemID.GRIMY_RANARR_WEED, Skill.HERBLORE, "Grimy Herbs"),
GRIMY_TOADFLAX(ItemID.GRIMY_TOADFLAX, Skill.HERBLORE, "Grimy Herbs"),
GRIMY_IRIT_LEAF(ItemID.GRIMY_IRIT_LEAF, Skill.HERBLORE, "Grimy Herbs"),
GRIMY_AVANTOE(ItemID.GRIMY_AVANTOE, Skill.HERBLORE, "Grimy Herbs"),
GRIMY_KWUARM(ItemID.GRIMY_KWUARM, Skill.HERBLORE, "Grimy Herbs"),
GRIMY_SNAPDRAGON(ItemID.GRIMY_SNAPDRAGON, Skill.HERBLORE, "Grimy Herbs"),
GRIMY_CADANTINE(ItemID.GRIMY_CADANTINE, Skill.HERBLORE, "Grimy Herbs"),
GRIMY_LANTADYME(ItemID.GRIMY_LANTADYME, Skill.HERBLORE, "Grimy Herbs"),
GRIMY_DWARF_WEED(ItemID.GRIMY_DWARF_WEED, Skill.HERBLORE, "Grimy Herbs"),
GRIMY_TORSTOL(ItemID.GRIMY_TORSTOL, Skill.HERBLORE, "Grimy Herbs"),
// Clean Herbs
GUAM_LEAF(ItemID.GUAM_LEAF, Skill.HERBLORE, "Cleaned Herbs"),
MARRENTILL(ItemID.MARRENTILL, Skill.HERBLORE, "Cleaned Herbs"),
TARROMIN(ItemID.TARROMIN, Skill.HERBLORE, "Cleaned Herbs"),
HARRALANDER(ItemID.HARRALANDER, Skill.HERBLORE, "Cleaned Herbs"),
RANARR_WEED(ItemID.RANARR_WEED, Skill.HERBLORE, "Cleaned Herbs"),
TOADFLAX(ItemID.TOADFLAX, Skill.HERBLORE, "Cleaned Herbs"),
IRIT_LEAF(ItemID.IRIT_LEAF, Skill.HERBLORE, "Cleaned Herbs"),
AVANTOE(ItemID.AVANTOE, Skill.HERBLORE, "Cleaned Herbs"),
KWUARM(ItemID.KWUARM, Skill.HERBLORE, "Cleaned Herbs"),
SNAPDRAGON(ItemID.SNAPDRAGON, Skill.HERBLORE, "Cleaned Herbs"),
CADANTINE(ItemID.CADANTINE, Skill.HERBLORE, "Cleaned Herbs"),
LANTADYME(ItemID.LANTADYME, Skill.HERBLORE, "Cleaned Herbs"),
DWARF_WEED(ItemID.DWARF_WEED, Skill.HERBLORE, "Cleaned Herbs"),
TORSTOL(ItemID.TORSTOL, Skill.HERBLORE, "Cleaned Herbs"),
// Unfinished Potions
GUAM_LEAF_POTION_UNF(ItemID.GUAM_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
MARRENTILL_POTION_UNF(ItemID.MARRENTILL_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
TARROMIN_POTION_UNF(ItemID.TARROMIN_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
HARRALANDER_POTION_UNF(ItemID.HARRALANDER_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
RANARR_POTION_UNF(ItemID.RANARR_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
TOADFLAX_POTION_UNF(ItemID.TOADFLAX_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
IRIT_POTION_UNF(ItemID.IRIT_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
AVANTOE_POTION_UNF(ItemID.AVANTOE_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
KWUARM_POTION_UNF(ItemID.KWUARM_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
SNAPDRAGON_POTION_UNF(ItemID.SNAPDRAGON_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
CADANTINE_POTION_UNF(ItemID.CADANTINE_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
LANTADYME_POTION_UNF(ItemID.LANTADYME_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
DWARF_WEED_POTION_UNF(ItemID.DWARF_WEED_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
TORSTOL_POTION_UNF(ItemID.TORSTOL_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
/**
* Prayer Items
*/
// Bones
BONES(ItemID.BONES, Skill.PRAYER, "Bones"),
WOLF_BONES(ItemID.WOLF_BONES, Skill.PRAYER, "Bones"),
BURNT_BONES(ItemID.BURNT_BONES, Skill.PRAYER, "Bones"),
MONKEY_BONES(ItemID.MONKEY_BONES, Skill.PRAYER, "Bones"),
BAT_BONES(ItemID.BAT_BONES, Skill.PRAYER, "Bones"),
JOGRE_BONES(ItemID.JOGRE_BONES, Skill.PRAYER, "Bones"),
BIG_BONES(ItemID.BIG_BONES, Skill.PRAYER, "Bones"),
ZOGRE_BONES(ItemID.ZOGRE_BONES, Skill.PRAYER, "Bones"),
SHAIKAHAN_BONES(ItemID.SHAIKAHAN_BONES, Skill.PRAYER, "Bones"),
BABYDRAGON_BONES(ItemID.BABYDRAGON_BONES, Skill.PRAYER, "Bones"),
WYVERN_BONES(ItemID.WYVERN_BONES, Skill.PRAYER, "Bones"),
DRAGON_BONES(ItemID.DRAGON_BONES, Skill.PRAYER, "Bones"),
FAYRG_BONES(ItemID.FAYRG_BONES, Skill.PRAYER, "Bones"),
LAVA_DRAGON_BONES(ItemID.LAVA_DRAGON_BONES, Skill.PRAYER, "Bones"),
RAURG_BONES(ItemID.RAURG_BONES, Skill.PRAYER, "Bones"),
DAGANNOTH_BONES(ItemID.DAGANNOTH_BONES, Skill.PRAYER, "Bones"),
OURG_BONES(ItemID.OURG_BONES, Skill.PRAYER, "Bones"),
SUPERIOR_DRAGON_BONES(ItemID.SUPERIOR_DRAGON_BONES, Skill.PRAYER, "Bones"),
// Shade Remains (Pyre Logs)
LOAR_REMAINS(ItemID.LOAR_REMAINS, Skill.PRAYER, "Shades", true),
PHRIN_REMAINS(ItemID.PHRIN_REMAINS, Skill.PRAYER, "Shades", true),
RIYL_REMAINS(ItemID.RIYL_REMAINS, Skill.PRAYER, "Shades", true),
ASYN_REMAINS(ItemID.ASYN_REMAINS, Skill.PRAYER, "Shades", true),
FIYR_REMAINS(ItemID.FIYR_REMAINS, Skill.PRAYER, "Shades", true),
// Ensouled Heads
ENSOULED_GOBLIN_HEAD(ItemID.ENSOULED_GOBLIN_HEAD_13448, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_MONKEY_HEAD(ItemID.ENSOULED_MONKEY_HEAD_13451, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_IMP_HEAD(ItemID.ENSOULED_IMP_HEAD_13454, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_MINOTAUR_HEAD(ItemID.ENSOULED_MINOTAUR_HEAD_13457, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_SCORPION_HEAD(ItemID.ENSOULED_SCORPION_HEAD_13460, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_BEAR_HEAD(ItemID.ENSOULED_BEAR_HEAD_13463, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_UNICORN_HEAD(ItemID.ENSOULED_UNICORN_HEAD_13466, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_DOG_HEAD(ItemID.ENSOULED_DOG_HEAD_13469, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_CHAOS_DRUID_HEAD(ItemID.ENSOULED_CHAOS_DRUID_HEAD_13472, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_GIANT_HEAD(ItemID.ENSOULED_GIANT_HEAD_13475, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_OGRE_HEAD(ItemID.ENSOULED_OGRE_HEAD_13478, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_ELF_HEAD(ItemID.ENSOULED_ELF_HEAD_13481, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_TROLL_HEAD(ItemID.ENSOULED_TROLL_HEAD_13484, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_HORROR_HEAD(ItemID.ENSOULED_HORROR_HEAD_13487, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_KALPHITE_HEAD(ItemID.ENSOULED_KALPHITE_HEAD_13490, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_DAGANNOTH_HEAD(ItemID.ENSOULED_DAGANNOTH_HEAD_13493, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_BLOODVELD_HEAD(ItemID.ENSOULED_BLOODVELD_HEAD_13496, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_TZHAAR_HEAD(ItemID.ENSOULED_TZHAAR_HEAD_13499, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_DEMON_HEAD(ItemID.ENSOULED_DEMON_HEAD_13502, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_AVIANSIE_HEAD(ItemID.ENSOULED_AVIANSIE_HEAD_13505, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_ABYSSAL_HEAD(ItemID.ENSOULED_ABYSSAL_HEAD_13508, Skill.PRAYER, "Ensouled Heads", true),
ENSOULED_DRAGON_HEAD(ItemID.ENSOULED_DRAGON_HEAD_13511, Skill.PRAYER, "Ensouled Heads", true),
/**
* Cooking Items
*/
RAW_HERRING(ItemID.RAW_HERRING, Skill.COOKING, "Fish"),
RAW_MACKEREL(ItemID.RAW_MACKEREL, Skill.COOKING, "Fish"),
RAW_TROUT(ItemID.RAW_TROUT, Skill.COOKING, "Fish"),
RAW_COD(ItemID.RAW_COD, Skill.COOKING, "Fish"),
RAW_PIKE(ItemID.RAW_PIKE, Skill.COOKING, "Fish"),
RAW_SALMON(ItemID.RAW_SALMON, Skill.COOKING, "Fish"),
RAW_TUNA(ItemID.RAW_TUNA, Skill.COOKING, "Fish"),
RAW_KARAMBWAN(ItemID.RAW_KARAMBWAN, Skill.COOKING, "Fish"),
RAW_LOBSTER(ItemID.RAW_LOBSTER, Skill.COOKING, "Fish"),
RAW_BASS(ItemID.RAW_BASS, Skill.COOKING, "Fish"),
RAW_SWORDFISH(ItemID.RAW_SWORDFISH, Skill.COOKING, "Fish"),
RAW_MONKFISH(ItemID.RAW_MONKFISH, Skill.COOKING, "Fish"),
RAW_SHARK(ItemID.RAW_SHARK, Skill.COOKING, "Fish"),
RAW_SEA_TURTLE(ItemID.RAW_SEA_TURTLE, Skill.COOKING, "Fish"),
RAW_ANGLERFISH(ItemID.RAW_ANGLERFISH, Skill.COOKING, "Fish"),
RAW_DARK_CRAB(ItemID.RAW_DARK_CRAB, Skill.COOKING, "Fish"),
RAW_MANTA_RAY(ItemID.RAW_MANTA_RAY, Skill.COOKING, "Fish"),
GRAPES(ItemID.GRAPES, Skill.COOKING, "Other"),
/**
* Crafting Items
*/
WOOL(ItemID.WOOL, Skill.CRAFTING, "Misc"),
FLAX(ItemID.FLAX, Skill.CRAFTING, "Misc"),
MOLTEN_GLASS(ItemID.MOLTEN_GLASS, Skill.CRAFTING, "Misc"),
BATTLESTAFF(ItemID.BATTLESTAFF, Skill.CRAFTING, "Misc"),
// D'hide/Dragon Leather
GREEN_DRAGONHIDE(ItemID.GREEN_DRAGONHIDE, Skill.CRAFTING, "D'hide"),
GREEN_DRAGON_LEATHER(ItemID.GREEN_DRAGON_LEATHER, Skill.CRAFTING, "D'hide"),
BLUE_DRAGONHIDE(ItemID.BLUE_DRAGONHIDE, Skill.CRAFTING, "D'hide"),
BLUE_DRAGON_LEATHER(ItemID.BLUE_DRAGON_LEATHER, Skill.CRAFTING, "D'hide"),
RED_DRAGONHIDE(ItemID.RED_DRAGONHIDE, Skill.CRAFTING, "D'hide"),
RED_DRAGON_LEATHER(ItemID.RED_DRAGON_LEATHER, Skill.CRAFTING, "D'hide"),
BLACK_DRAGONHIDE(ItemID.BLACK_DRAGONHIDE, Skill.CRAFTING, "D'hide"),
BLACK_DRAGON_LEATHER(ItemID.BLACK_DRAGON_LEATHER, Skill.CRAFTING, "D'hide"),
// Uncut Gems
UNCUT_OPAL(ItemID.UNCUT_OPAL, Skill.CRAFTING, "Gems"),
UNCUT_JADE(ItemID.UNCUT_JADE, Skill.CRAFTING, "Gems"),
UNCUT_RED_TOPAZ(ItemID.UNCUT_RED_TOPAZ, Skill.CRAFTING, "Gems"),
UNCUT_SAPPHIRE(ItemID.UNCUT_SAPPHIRE, Skill.CRAFTING, "Gems"),
UNCUT_EMERALD(ItemID.UNCUT_EMERALD, Skill.CRAFTING, "Gems"),
UNCUT_RUBY(ItemID.UNCUT_RUBY, Skill.CRAFTING, "Gems"),
UNCUT_DIAMOND(ItemID.UNCUT_DIAMOND, Skill.CRAFTING, "Gems"),
UNCUT_DRAGONSTONE(ItemID.UNCUT_DRAGONSTONE, Skill.CRAFTING, "Gems"),
UNCUT_ONYX(ItemID.UNCUT_ONYX, Skill.CRAFTING, "Gems"),
UNCUT_ZENYTE(ItemID.UNCUT_ZENYTE, Skill.CRAFTING, "Gems"),
// Cut Gems
OPAL(ItemID.OPAL, Skill.CRAFTING, "Gems"),
JADE(ItemID.JADE, Skill.CRAFTING, "Gems"),
RED_TOPAZ(ItemID.RED_TOPAZ, Skill.CRAFTING, "Gems"),
SAPPHIRE(ItemID.SAPPHIRE, Skill.CRAFTING, "Gems"),
EMERALD(ItemID.EMERALD, Skill.CRAFTING, "Gems"),
RUBY(ItemID.RUBY, Skill.CRAFTING, "Gems"),
DIAMOND(ItemID.DIAMOND, Skill.CRAFTING, "Gems"),
DRAGONSTONE(ItemID.DRAGONSTONE, Skill.CRAFTING, "Gems"),
ONYX(ItemID.ONYX, Skill.CRAFTING, "Gems"),
ZENYTE(ItemID.ZENYTE, Skill.CRAFTING, "Gems"),
/**
* Smithing Items
*/
// Ores
IRON_ORE(ItemID.IRON_ORE, Skill.SMITHING, "Ore"),
SILVER_ORE(ItemID.SILVER_ORE, Skill.SMITHING, "Ore"),
GOLD_ORE(ItemID.GOLD_ORE, Skill.SMITHING, "Ore"),
MITHRIL_ORE(ItemID.MITHRIL_ORE, Skill.SMITHING, "Ore"),
ADAMANTITE_ORE(ItemID.ADAMANTITE_ORE, Skill.SMITHING, "Ore"),
RUNITE_ORE(ItemID.RUNITE_ORE, Skill.SMITHING, "Ore"),
// Bars
BRONZE_BAR(ItemID.BRONZE_BAR, Skill.SMITHING, "Bars"),
IRON_BAR(ItemID.IRON_BAR, Skill.SMITHING, "Bars"),
STEEL_BAR(ItemID.STEEL_BAR, Skill.SMITHING, "Bars"),
MITHRIL_BAR(ItemID.MITHRIL_BAR, Skill.SMITHING, "Bars"),
ADAMANTITE_BAR(ItemID.ADAMANTITE_BAR, Skill.SMITHING, "Bars"),
RUNITE_BAR(ItemID.RUNITE_BAR, Skill.SMITHING, "Bars"),
/**
* Farming Items
*/
// Seeds
ACORN(ItemID.ACORN, Skill.FARMING, "Seeds"),
WILLOW_SEED(ItemID.WILLOW_SEED, Skill.FARMING, "Seeds"),
MAPLE_SEED(ItemID.MAPLE_SEED, Skill.FARMING, "Seeds"),
YEW_SEED(ItemID.YEW_SEED, Skill.FARMING, "Seeds"),
MAGIC_SEED(ItemID.MAGIC_SEED, Skill.FARMING, "Seeds"),
APPLE_TREE_SEED(ItemID.APPLE_TREE_SEED, Skill.FARMING, "Seeds"),
BANANA_TREE_SEED(ItemID.BANANA_TREE_SEED, Skill.FARMING, "Seeds"),
ORANGE_TREE_SEED(ItemID.ORANGE_TREE_SEED, Skill.FARMING, "Seeds"),
CURRY_TREE_SEED(ItemID.CURRY_TREE_SEED, Skill.FARMING, "Seeds"),
PINEAPPLE_SEED(ItemID.PINEAPPLE_SEED, Skill.FARMING, "Seeds"),
PAPAYA_TREE_SEED(ItemID.PAPAYA_TREE_SEED, Skill.FARMING, "Seeds"),
PALM_TREE_SEED(ItemID.PALM_TREE_SEED, Skill.FARMING, "Seeds"),
CALQUAT_TREE_SEED(ItemID.CALQUAT_TREE_SEED, Skill.FARMING, "Seeds"),
TEAK_SEED(ItemID.TEAK_SEED, Skill.FARMING, "Seeds"),
MAHOGANY_SEED(ItemID.MAHOGANY_SEED, Skill.FARMING, "Seeds"),
SPIRIT_SEED(ItemID.SPIRIT_SEED, Skill.FARMING, "Seeds"),
// Saplings
OAK_SAPLING(ItemID.OAK_SAPLING, Skill.FARMING, "Saplings"),
WILLOW_SAPLING(ItemID.WILLOW_SAPLING, Skill.FARMING, "Saplings"),
MAPLE_SAPLING(ItemID.MAPLE_SAPLING, Skill.FARMING, "Saplings"),
YEW_SAPLING(ItemID.YEW_SAPLING, Skill.FARMING, "Saplings"),
MAGIC_SAPLING(ItemID.MAGIC_SAPLING, Skill.FARMING, "Saplings"),
APPLE_TREE_SAPLING(ItemID.APPLE_SAPLING, Skill.FARMING, "Saplings"),
BANANA_TREE_SAPLING(ItemID.BANANA_SAPLING, Skill.FARMING, "Saplings"),
ORANGE_TREE_SAPLING(ItemID.ORANGE_SAPLING, Skill.FARMING, "Saplings"),
CURRY_TREE_SAPLING(ItemID.CURRY_SAPLING, Skill.FARMING, "Saplings"),
PINEAPPLE_SAPLING(ItemID.PINEAPPLE_SAPLING, Skill.FARMING, "Saplings"),
PAPAYA_TREE_SAPLING(ItemID.PAPAYA_SAPLING, Skill.FARMING, "Saplings"),
PALM_TREE_SAPLING(ItemID.PALM_SAPLING, Skill.FARMING, "Saplings"),
CALQUAT_TREE_SAPLING(ItemID.CALQUAT_SAPLING, Skill.FARMING, "Saplings"),
TEAK_SAPLING(ItemID.TEAK_SAPLING, Skill.FARMING, "Saplings"),
MAHOGANY_SAPLING(ItemID.MAHOGANY_SAPLING, Skill.FARMING, "Saplings"),
SPIRIT_SAPLING(ItemID.SPIRIT_SAPLING, Skill.FARMING, "Saplings"),
;
private final int itemID;
private final Skill skill;
private final String category;
private boolean ignoreBonus;
@Setter
// Stores the item composition info we use since we don't operate on the game thread
private ItemInfo itemInfo = null;
@Setter
private Activity selectedActivity;
private static final Multimap<Skill, CriticalItem> SKILL_MAP = ArrayListMultimap.create();
private static final Map<Integer, CriticalItem> ITEM_ID_MAP = new HashMap<>();
static
{
for (CriticalItem i : values())
{
Skill s = i.getSkill();
SKILL_MAP.put(s, i);
ITEM_ID_MAP.put(i.getItemID(), i);
}
}
CriticalItem(int itemID, Skill skill, String category, boolean ignoreBonus)
{
this.itemID = itemID;
this.category = category;
this.skill = skill;
this.ignoreBonus = ignoreBonus;
}
CriticalItem(int itemID, Skill skill, String category)
{
this(itemID, skill, category, false);
}
public static Collection<CriticalItem> getBySkill(Skill skill)
{
Collection<CriticalItem> items = SKILL_MAP.get(skill);
if (items == null)
{
items = new ArrayList<>();
}
return items;
}
public static CriticalItem getByItemId(int id)
{
return ITEM_ID_MAP.get(id);
}
/**
* Attaches the Item Composition to each CriticalItem on client initial load
*
* @param m ItemManager
*/
public static void prepareItemDefinitions(ItemManager m)
{
for (CriticalItem i : values())
{
if (i.itemInfo != null)
{
return;
}
final ItemDefinition c = m.getItemDefinition(i.getItemID());
i.itemInfo = new ItemInfo(c.getName(), c.isStackable());
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,23 +24,13 @@
*/
package net.runelite.client.plugins.skillcalculator.banked.beans;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.AllArgsConstructor;
import lombok.Data;
@Getter(AccessLevel.PUBLIC)
public class SecondaryItem
@Data
@AllArgsConstructor
public class ItemInfo
{
private final int id;
private final int qty;
SecondaryItem(int id, int qty)
{
this.id = id;
this.qty = qty;
}
SecondaryItem(int id)
{
this(id, 1);
}
}
private String name;
private boolean stackable;
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.skillcalculator.banked.beans;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
class ItemStack
{
private int id;
private int qty;
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.skillcalculator.banked.beans;
import lombok.Getter;
import net.runelite.api.ItemID;
@Getter
public enum Secondaries
{
/**
* Herblore
*/
UNFINISHED_POTION(new ItemStack(ItemID.VIAL_OF_WATER, 1)),
SWAMP_TAR(new ItemStack(ItemID.SWAMP_TAR, 15)),
// Guam
ATTACK_POTION(new ItemStack(ItemID.EYE_OF_NEWT, 1)),
// Marrentil
ANTIPOISON(new ItemStack(ItemID.UNICORN_HORN_DUST, 1)),
// Tarromin
STRENGTH_POTION(new ItemStack(ItemID.LIMPWURT_ROOT, 1)),
SERUM_207(new ItemStack(ItemID.ASHES, 1)),
// Harralander
COMPOST_POTION(new ItemStack(ItemID.VOLCANIC_ASH, 1)),
RESTORE_POTION(new ItemStack(ItemID.RED_SPIDERS_EGGS, 1)),
ENERGY_POTION(new ItemStack(ItemID.CHOCOLATE_DUST, 1)),
COMBAT_POTION(new ItemStack(ItemID.GOAT_HORN_DUST, 1)),
// Ranarr Weed
DEFENCE_POTION(new ItemStack(ItemID.WHITE_BERRIES, 1)),
PRAYER_POTION(new ItemStack(ItemID.SNAPE_GRASS, 1)),
// Toadflax
AGILITY_POTION(new ItemStack(ItemID.TOADS_LEGS, 1)),
SARADOMIN_BREW(new ItemStack(ItemID.CRUSHED_NEST, 1)),
// Irit
SUPER_ATTACK(new ItemStack(ItemID.EYE_OF_NEWT, 1)),
SUPERANTIPOISON(new ItemStack(ItemID.UNICORN_HORN_DUST, 1)),
// Avantoe
FISHING_POTION(new ItemStack(ItemID.SNAPE_GRASS, 1)),
SUPER_ENERGY_POTION(new ItemStack(ItemID.MORT_MYRE_FUNGUS, 1)),
HUNTER_POTION(new ItemStack(ItemID.KEBBIT_TEETH_DUST, 1)),
// Kwuarm
SUPER_STRENGTH(new ItemStack(ItemID.LIMPWURT_ROOT, 1)),
// Snapdragon
SUPER_RESTORE(new ItemStack(ItemID.RED_SPIDERS_EGGS, 1)),
SANFEW_SERUM(new ItemStack(ItemID.SNAKE_WEED, 1), new ItemStack(ItemID.UNICORN_HORN_DUST, 1), new ItemStack(ItemID.SUPER_RESTORE4, 1), new ItemStack(ItemID.NAIL_BEAST_NAILS, 1)),
// Cadantine
SUPER_DEFENCE_POTION(new ItemStack(ItemID.WHITE_BERRIES, 1)),
// Lantadyme
ANTIFIRE_POTION(new ItemStack(ItemID.DRAGON_SCALE_DUST, 1)),
MAGIC_POTION(new ItemStack(ItemID.POTATO_CACTUS, 1)),
// Dwarf Weed
RANGING_POTION(new ItemStack(ItemID.WINE_OF_ZAMORAK, 1)),
// Torstol
ZAMORAK_BREW(new ItemStack(ItemID.JANGERBERRIES, 1)),
SUPER_COMBAT_POTION(new ItemStack(ItemID.SUPER_ATTACK4, 1), new ItemStack(ItemID.SUPER_STRENGTH4, 1), new ItemStack(ItemID.SUPER_DEFENCE4, 1)),
ANTIVENOM_PLUS(new ItemStack(ItemID.ANTIVENOM4, 1)),
/**
* Smithing
*/
COAL_ORE(new ItemStack(ItemID.COAL, 1)),
COAL_ORE_2(new ItemStack(ItemID.COAL, 2)),
COAL_ORE_4(new ItemStack(ItemID.COAL, 4)),
COAL_ORE_6(new ItemStack(ItemID.COAL, 6)),
COAL_ORE_8(new ItemStack(ItemID.COAL, 8)),
/**
* Crafting
*/
GOLD_BAR(new ItemStack(ItemID.GOLD_BAR, 1)),
SILVER_BAR(new ItemStack(ItemID.SILVER_BAR, 1)),
WATER_ORB(new ItemStack(ItemID.WATER_ORB, 1)),
EARTH_ORB(new ItemStack(ItemID.EARTH_ORB, 1)),
FIRE_ORB(new ItemStack(ItemID.FIRE_ORB, 1)),
AIR_ORB(new ItemStack(ItemID.AIR_ORB, 1)),
/**
* Construction
*/
COINS_100(new ItemStack(ItemID.COINS_995, 100)),
COINS_250(new ItemStack(ItemID.COINS_995, 250)),
COINS_500(new ItemStack(ItemID.COINS_995, 500)),
COINS_1500(new ItemStack(ItemID.COINS_995, 1500)),
/**
* Cooking
*/
JUG_OF_WATER(new ItemStack(ItemID.JUG_OF_WATER, 1)),
;
private final ItemStack[] items;
Secondaries(ItemStack... items)
{
this.items = items;
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.skillcalculator.banked.beans;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import java.util.Collection;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.api.Skill;
@AllArgsConstructor
@Getter
public enum XpModifiers
{
LIT_GILDER_ALTAR(Skill.PRAYER, "Lit Gilded Altar (350%)", 3.5f),
ECTOFUNTUS(Skill.PRAYER, "Ectofuntus (400%)", 4),
WILDY_ALTAR(Skill.PRAYER, "Wildy Altar (700%)", 7),
FARMERS_OUTFIT(Skill.FARMING, "Farmer's Outfit (+2.5%)", 1.025f);
private final Skill skill;
private final String name;
private final float modifier;
private final static Multimap<Skill, XpModifiers> MODIFIERS_MAP;
static
{
final ImmutableMultimap.Builder<Skill, XpModifiers> map = ImmutableMultimap.builder();
for (final XpModifiers m : values())
{
map.put(m.skill, m);
}
MODIFIERS_MAP = map.build();
}
public static Collection<XpModifiers> getModifiersBySkill(final Skill skill)
{
return MODIFIERS_MAP.get(skill);
}
}

View File

@@ -0,0 +1,201 @@
/*
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.skillcalculator.banked.components;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.function.BooleanSupplier;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import net.runelite.client.game.AsyncBufferedImage;
import net.runelite.client.plugins.skillcalculator.banked.BankedCalculator;
import net.runelite.client.plugins.skillcalculator.banked.beans.Activity;
import net.runelite.client.plugins.skillcalculator.banked.beans.BankedItem;
import net.runelite.client.ui.ColorScheme;
@Getter(AccessLevel.PUBLIC)
public class GridItem extends JLabel
{
private final static String IGNORE = "Ignore Item";
private final static String INCLUDE = "Include Item";
private static final Color UNSELECTED_BACKGROUND = ColorScheme.DARKER_GRAY_COLOR;
private static final Color UNSELECTED_HOVER_BACKGROUND = ColorScheme.DARKER_GRAY_HOVER_COLOR;
private static final Color SELECTED_BACKGROUND = new Color(0, 70, 0);
private static final Color SELECTED_HOVER_BACKGROUND = new Color(0, 100, 0);
private static final Color IGNORED_BACKGROUND = new Color(90, 0, 0);
private static final Color IGNORED_HOVER_BACKGROUND = new Color(120, 0, 0);
/* To be executed when this element is clicked */
@Setter(AccessLevel.PUBLIC)
private BooleanSupplier onSelectEvent;
/* To be executed when this element is ignored */
@Setter(AccessLevel.PUBLIC)
private BooleanSupplier onIgnoreEvent;
private final SelectionGrid parent;
private final BankedItem bankedItem;
private int amount;
private boolean selected = false;
private boolean ignored = false;
private final JMenuItem IGNORE_OPTION = new JMenuItem(IGNORE);
GridItem(final SelectionGrid parent, final BankedItem item, final AsyncBufferedImage icon, final int amount)
{
super("");
this.parent = parent;
this.bankedItem = item;
this.setOpaque(true);
this.setBackground(ColorScheme.DARKER_GRAY_COLOR);
this.setBorder(BorderFactory.createEmptyBorder(5, 0, 2, 0));
this.setVerticalAlignment(SwingConstants.CENTER);
this.setHorizontalAlignment(SwingConstants.CENTER);
updateIcon(icon, amount);
updateToolTip();
this.addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent mouseEvent)
{
if (mouseEvent.getButton() == MouseEvent.BUTTON1)
{
select();
}
}
@Override
public void mouseEntered(MouseEvent e)
{
final GridItem item = (GridItem) e.getSource();
item.setBackground(getHoverBackgroundColor());
}
@Override
public void mouseExited(MouseEvent e)
{
final GridItem item = (GridItem) e.getSource();
item.setBackground(getBackgroundColor());
}
});
IGNORE_OPTION.addActionListener(e ->
{
// Update ignored flag now so event knows new state
this.ignored = !this.ignored;
if (onIgnoreEvent != null && !onIgnoreEvent.getAsBoolean())
{
// Reset state
this.ignored = !this.ignored;
return;
}
IGNORE_OPTION.setText(this.ignored ? INCLUDE : IGNORE);
this.setBackground(getBackgroundColor());
});
final JPopupMenu popupMenu = new JPopupMenu();
popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5));
popupMenu.add(IGNORE_OPTION);
this.setComponentPopupMenu(popupMenu);
}
private Color getBackgroundColor()
{
return ignored ? IGNORED_BACKGROUND : (selected ? SELECTED_BACKGROUND : UNSELECTED_BACKGROUND);
}
private Color getHoverBackgroundColor()
{
return ignored ? IGNORED_HOVER_BACKGROUND : (selected ? SELECTED_HOVER_BACKGROUND : UNSELECTED_HOVER_BACKGROUND);
}
public void select()
{
if (onSelectEvent != null && !onSelectEvent.getAsBoolean())
{
return;
}
selected = true;
setBackground(getBackgroundColor());
}
void unselect()
{
selected = false;
setBackground(getBackgroundColor());
}
public void updateIcon(final AsyncBufferedImage icon, final int amount)
{
icon.addTo(this);
this.amount = amount;
}
public void updateToolTip()
{
this.setToolTipText(buildToolTip());
}
private String buildToolTip()
{
String tip = "<html>" + bankedItem.getItem().getItemInfo().getName();
final Activity a = bankedItem.getItem().getSelectedActivity();
if (a != null)
{
final double xp = parent.getCalc().getItemXpRate(bankedItem);
tip += "<br/>Activity: " + a.getName();
tip += "<br/>Xp/Action: " + BankedCalculator.XP_FORMAT_COMMA.format(xp);
tip += "<br/>Total Xp: " + BankedCalculator.XP_FORMAT_COMMA.format(xp * amount);
}
else
{
tip += "<br/>Outputs: " + bankedItem.getItem().getItemInfo().getName();
}
return tip + "</html>";
}
}

View File

@@ -0,0 +1,354 @@
/*
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.skillcalculator.banked.components;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ItemEvent;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import lombok.AccessLevel;
import lombok.Getter;
import net.runelite.api.Constants;
import net.runelite.client.game.AsyncBufferedImage;
import net.runelite.client.game.ItemManager;
import net.runelite.client.plugins.skillcalculator.banked.BankedCalculator;
import net.runelite.client.plugins.skillcalculator.banked.beans.Activity;
import net.runelite.client.plugins.skillcalculator.banked.beans.BankedItem;
import net.runelite.client.plugins.skillcalculator.banked.beans.CriticalItem;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.components.ComboBoxIconEntry;
import net.runelite.client.ui.components.ComboBoxListRenderer;
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
public class ModifyPanel extends JPanel
{
private static final Dimension ICON_SIZE = new Dimension(Constants.ITEM_SPRITE_WIDTH, Constants.ITEM_SPRITE_HEIGHT);
private static final DecimalFormat FORMAT_COMMA = new DecimalFormat("#,###.#");
private static final Border PANEL_BORDER = new EmptyBorder(3, 0, 3, 0);
private static final Color BACKGROUND_COLOR = ColorScheme.DARKER_GRAY_COLOR;
private final BankedCalculator calc;
private final ItemManager itemManager;
@Getter(AccessLevel.PUBLIC)
private BankedItem bankedItem;
private Map<CriticalItem, Integer> linkedMap;
@Getter(AccessLevel.PUBLIC)
private int amount = 0;
@Getter(AccessLevel.PUBLIC)
private double total = 0;
// Banked item information display
private final JPanel labelContainer;
private final JLabel image;
private final JShadowedLabel labelName;
private final JShadowedLabel labelValue;
// Elements used to adjust banked item
private final JPanel adjustContainer;
public ModifyPanel(final BankedCalculator calc, final ItemManager itemManager)
{
this.calc = calc;
this.itemManager = itemManager;
this.setLayout(new GridBagLayout());
this.setBorder(PANEL_BORDER);
this.setBackground(ColorScheme.DARK_GRAY_COLOR);
// Banked item information display
labelContainer = new JPanel();
labelContainer.setLayout(new BorderLayout());
labelContainer.setBackground(BACKGROUND_COLOR);
labelContainer.setBorder(new EmptyBorder(5, 0, 5, 0));
// Icon
image = new JLabel();
image.setMinimumSize(ICON_SIZE);
image.setMaximumSize(ICON_SIZE);
image.setPreferredSize(ICON_SIZE);
image.setHorizontalAlignment(SwingConstants.CENTER);
image.setBorder(new EmptyBorder(0, 8, 0, 0));
// Wrapper panel for the shadowed labels
final JPanel uiInfo = new JPanel(new GridLayout(2, 1));
uiInfo.setBorder(new EmptyBorder(0, 5, 0, 0));
uiInfo.setBackground(BACKGROUND_COLOR);
labelName = new JShadowedLabel();
labelName.setForeground(Color.WHITE);
labelName.setVerticalAlignment(SwingUtilities.BOTTOM);
labelValue = new JShadowedLabel();
labelValue.setFont(FontManager.getRunescapeSmallFont());
labelValue.setVerticalAlignment(SwingUtilities.TOP);
uiInfo.add(labelName);
uiInfo.add(labelValue);
// Append elements to item info panel
labelContainer.add(image, BorderLayout.LINE_START);
labelContainer.add(uiInfo, BorderLayout.CENTER);
// Container for tools to adjust banked calculation for this item
adjustContainer = new JPanel();
adjustContainer.setLayout(new GridBagLayout());
adjustContainer.setBackground(BACKGROUND_COLOR);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.gridx = 0;
c.gridy = 0;
c.ipady = 0;
this.add(labelContainer, c);
c.gridy++;
this.add(adjustContainer, c);
}
// Updates the UI for the selected item
public void setBankedItem(final BankedItem bankedItem)
{
if (bankedItem == null)
{
return;
}
this.bankedItem = bankedItem;
if (this.calc.getConfig().cascadeBankedXp())
{
this.linkedMap = this.calc.createLinksMap(bankedItem);
this.amount = bankedItem.getQty();
for (int i : linkedMap.values())
{
this.amount += i;
}
}
else
{
this.linkedMap = new HashMap<>();
this.amount = this.calc.getItemQty(bankedItem);
}
updateImageTooltip();
updateLabelContainer();
updateAdjustContainer();
}
private void updateImageTooltip()
{
final StringBuilder b = new StringBuilder("<html>");
b.append(bankedItem.getQty()).append(" x ").append(bankedItem.getItem().getItemInfo().getName());
for (final Map.Entry<CriticalItem, Integer> e : this.linkedMap.entrySet())
{
b.append("<br/>").append(e.getValue()).append(" x ").append(e.getKey().getItemInfo().getName());
}
b.append("</html>");
this.image.setToolTipText(b.toString());
}
private void updateLabelContainer()
{
final CriticalItem item = bankedItem.getItem();
// Update image icon
final boolean stackable = item.getItemInfo().isStackable() || amount > 1;
final AsyncBufferedImage icon = itemManager.getImage(item.getItemID(), amount, stackable);
final Runnable resize = () -> image.setIcon(new ImageIcon(icon.getScaledInstance(ICON_SIZE.width, ICON_SIZE.height, Image.SCALE_SMOOTH)));
icon.onChanged(resize);
resize.run();
final String itemName = item.getItemInfo().getName();
labelName.setText(itemName);
double xp = calc.getItemXpRate(bankedItem);
total = amount * xp;
final String value = FORMAT_COMMA.format(total) + "xp";
labelValue.setText(value);
labelContainer.setToolTipText("<html>" + itemName
+ "<br/>xp: " + xp
+ "<br/>Total: " + total + "</html");
labelContainer.revalidate();
labelContainer.repaint();
}
private void updateAdjustContainer()
{
adjustContainer.removeAll();
final JLabel label = new JLabel("Output:");
label.setVerticalAlignment(JLabel.CENTER);
label.setHorizontalAlignment(JLabel.CENTER);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridx = 0;
c.gridy = 0;
c.ipady = 0;
adjustContainer.add(label, c);
c.gridy++;
final float xpFactor = (bankedItem.getItem().isIgnoreBonus() ? 1.0f : this.calc.getXpFactor());
final List<Activity> activities = Activity.getByCriticalItem(bankedItem.getItem(), calc.getSkillLevel());
if (activities == null || activities.size() == 0)
{
adjustContainer.add(new JLabel("Unknown"));
}
else if (activities.size() == 1)
{
final Activity a = activities.get(0);
final AsyncBufferedImage img = itemManager.getImage(a.getIcon());
final ImageIcon icon = new ImageIcon(img);
final double xp = a.getXp() * xpFactor;
final JPanel container = createShadowedLabel(icon, a.getName(), FORMAT_COMMA.format(xp) + "xp");
img.onChanged(() ->
{
icon.setImage(img);
container.repaint();
});
adjustContainer.add(container, c);
}
else
{
final JComboBox<ComboBoxIconEntry> dropdown = new JComboBox<>();
final ComboBoxListRenderer renderer = new ComboBoxListRenderer();
dropdown.setRenderer(renderer);
for (final Activity option : activities)
{
final double xp = option.getXp() * xpFactor;
String name = option.getName();
if (xp > 0)
{
name += " (" + FORMAT_COMMA.format(xp) + "xp)";
}
final AsyncBufferedImage img = itemManager.getImage(option.getIcon());
final ImageIcon icon = new ImageIcon(img);
final ComboBoxIconEntry entry = new ComboBoxIconEntry(icon, name, option);
dropdown.addItem(entry);
img.onChanged(() ->
{
icon.setImage(img);
dropdown.revalidate();
dropdown.repaint();
});
final Activity selected = bankedItem.getItem().getSelectedActivity();
if (option.equals(selected))
{
dropdown.setSelectedItem(entry);
}
}
// Add click event handler now to prevent above code from triggering it.
dropdown.addItemListener(e ->
{
if (e.getStateChange() == ItemEvent.SELECTED && e.getItem() instanceof ComboBoxIconEntry)
{
final ComboBoxIconEntry source = (ComboBoxIconEntry) e.getItem();
if (source.getData() instanceof Activity)
{
final Activity selectedActivity = ((Activity) source.getData());
calc.activitySelected(bankedItem, selectedActivity);
updateLabelContainer();
}
}
});
adjustContainer.add(dropdown, c);
}
}
private JPanel createShadowedLabel(final ImageIcon icon, final String name, final String value)
{
// Wrapper panel for the shadowed labels
final JPanel wrapper = new JPanel(new GridLayout(2, 1));
wrapper.setBorder(new EmptyBorder(0, 5, 0, 0));
wrapper.setBackground(BACKGROUND_COLOR);
final JShadowedLabel nameLabel = new JShadowedLabel(name);
nameLabel.setForeground(Color.WHITE);
nameLabel.setVerticalAlignment(SwingUtilities.BOTTOM);
final JShadowedLabel valueLabel = new JShadowedLabel(value);
valueLabel.setFont(FontManager.getRunescapeSmallFont());
valueLabel.setVerticalAlignment(SwingUtilities.TOP);
wrapper.add(nameLabel);
wrapper.add(valueLabel);
final JPanel container = new JPanel();
container.setLayout(new BorderLayout());
container.setBackground(BACKGROUND_COLOR);
container.setBorder(new EmptyBorder(5, 0, 5, 0));
final JLabel image = new JLabel();
image.setMinimumSize(ICON_SIZE);
image.setMaximumSize(ICON_SIZE);
image.setPreferredSize(ICON_SIZE);
image.setHorizontalAlignment(SwingConstants.CENTER);
image.setBorder(new EmptyBorder(0, 8, 0, 0));
image.setIcon(icon);
container.add(image, BorderLayout.LINE_START);
container.add(wrapper, BorderLayout.CENTER);
return container;
}
}

View File

@@ -0,0 +1,142 @@
/*
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.skillcalculator.banked.components;
import java.awt.GridLayout;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BooleanSupplier;
import java.util.stream.Collectors;
import javax.swing.JPanel;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import net.runelite.client.game.AsyncBufferedImage;
import net.runelite.client.game.ItemManager;
import net.runelite.client.plugins.skillcalculator.banked.BankedCalculator;
import net.runelite.client.plugins.skillcalculator.banked.beans.BankedItem;
/**
* A grid that supports mouse events
*/
public class SelectionGrid extends JPanel
{
private static final int ITEMS_PER_ROW = 5;
@Getter(AccessLevel.PUBLIC)
private final Map<BankedItem, GridItem> panelMap = new LinkedHashMap<>();
@Getter(AccessLevel.PUBLIC)
private BankedItem selectedItem;
@Getter(AccessLevel.PUBLIC)
private BankedItem lastIgnoredItem;
/* To be executed when this element is clicked */
@Setter(AccessLevel.PUBLIC)
private BooleanSupplier onSelectEvent;
/* To be executed when this element is ignored */
@Setter(AccessLevel.PUBLIC)
private BooleanSupplier onIgnoreEvent;
@Getter(AccessLevel.PUBLIC)
private final BankedCalculator calc;
public SelectionGrid(final BankedCalculator calc, final Collection<BankedItem> items, final ItemManager itemManager)
{
this.calc = calc;
// Create a panel for every item
for (final BankedItem item : items)
{
final int qty = calc.getItemQty(item);
final boolean stackable = item.getItem().getItemInfo().isStackable() || qty > 1;
final AsyncBufferedImage img = itemManager.getImage(item.getItem().getItemID(), qty, stackable);
final GridItem gridItem = new GridItem(this, item, img, qty);
gridItem.setOnSelectEvent(() -> selected(item));
gridItem.setOnIgnoreEvent(() -> ignore(item));
panelMap.put(item, gridItem);
}
refreshGridDisplay();
}
public void refreshGridDisplay()
{
this.removeAll();
final List<GridItem> items = panelMap.values().stream().filter(gi -> gi.getAmount() > 0).collect(Collectors.toList());
// Calculates how many rows need to be display to fit all items
final int rowSize = ((items.size() % ITEMS_PER_ROW == 0) ? 0 : 1) + items.size() / ITEMS_PER_ROW;
setLayout(new GridLayout(rowSize, ITEMS_PER_ROW, 1, 1));
for (final GridItem gridItem : items)
{
// Select the first option
if (selectedItem == null)
{
gridItem.select();
}
this.add(gridItem);
}
}
private boolean selected(final BankedItem item)
{
final BankedItem old = this.selectedItem;
if (item.equals(old))
{
return false;
}
// Set selected item now so the boolean can see what was just clicked
this.selectedItem = item;
if (onSelectEvent != null && !onSelectEvent.getAsBoolean())
{
this.selectedItem = old;
return false;
}
final GridItem gridItem = panelMap.get(old);
if (gridItem != null)
{
gridItem.unselect();
}
return true;
}
private boolean ignore(final BankedItem item)
{
this.lastIgnoredItem = item;
return onIgnoreEvent.getAsBoolean();
}
}

View File

@@ -1,402 +0,0 @@
/*
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.skillcalculator.banked.ui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.inject.Singleton;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.border.MatteBorder;
import lombok.AccessLevel;
import lombok.Getter;
import net.runelite.client.game.AsyncBufferedImage;
import net.runelite.client.game.ItemManager;
import net.runelite.client.plugins.skillcalculator.BankedCalculator;
import net.runelite.client.plugins.skillcalculator.banked.CriticalItem;
import net.runelite.client.plugins.skillcalculator.banked.beans.Activity;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.components.materialtabs.MaterialTab;
import net.runelite.client.ui.components.materialtabs.MaterialTabGroup;
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
import net.runelite.client.util.StackFormatter;
@Singleton
public class CriticalItemPanel extends JPanel
{
private static final Dimension ICON_SIZE = new Dimension(36, 36);
private static final DecimalFormat FORMAT_COMMA = new DecimalFormat("#,###.#");
private static final BufferedImage ICON_SETTINGS;
private static final Border PANEL_BORDER = new EmptyBorder(3, 0, 3, 0);
private final static Color BACKGROUND_COLOR = ColorScheme.DARKER_GRAY_COLOR;
private final static Color BUTTON_HOVER_COLOR = ColorScheme.DARKER_GRAY_HOVER_COLOR;
static
{
BufferedImage i1;
try
{
synchronized (ImageIO.class)
{
i1 = ImageIO.read(BankedCalculator.class.getResourceAsStream("view-more-white.png"));
}
}
catch (IOException e)
{
throw new RuntimeException(e);
}
ICON_SETTINGS = i1;
}
private final BankedCalculator bankedCalculator;
private final CriticalItem item;
private final ItemManager itemManager;
private double xp;
@Getter(AccessLevel.PUBLIC)
private int amount;
@Getter(AccessLevel.PUBLIC)
private double total;
private Map<CriticalItem, Integer> linkedMap;
private JShadowedLabel labelValue;
private final JPanel infoContainer;
private final JLabel image;
private boolean infoVisibility = false;
public CriticalItemPanel(BankedCalculator bankedCalculator, ItemManager itemManager, CriticalItem item, double xp, int amount, Map<CriticalItem, Integer> linkedMap)
{
this.bankedCalculator = bankedCalculator;
this.item = item;
this.xp = xp;
this.amount = amount;
this.total = xp * amount;
this.itemManager = itemManager;
this.linkedMap = linkedMap;
this.setLayout(new GridBagLayout());
this.setBorder(PANEL_BORDER);
this.setBackground(ColorScheme.DARK_GRAY_COLOR);
this.setVisible(this.amount > 0);
infoContainer = new JPanel();
infoContainer.setLayout(new GridBagLayout());
infoContainer.setVisible(false);
infoContainer.setBackground(BACKGROUND_COLOR);
infoContainer.setBorder(new MatteBorder(1, 0, 0, 0, Color.GRAY));
// Icon
AsyncBufferedImage icon = itemManager.getImage(item.getItemID(), amount, item.getDefinition().isStackable() || amount > 1);
image = new JLabel();
image.setMinimumSize(ICON_SIZE);
image.setMaximumSize(ICON_SIZE);
image.setPreferredSize(ICON_SIZE);
image.setHorizontalAlignment(SwingConstants.CENTER);
image.setBorder(new EmptyBorder(0, 8, 0, 0));
Runnable resize = () ->
image.setIcon(new ImageIcon(icon.getScaledInstance((int) ICON_SIZE.getWidth(), (int) ICON_SIZE.getHeight(), Image.SCALE_SMOOTH)));
icon.onChanged(resize);
resize.run();
// Container for Info
JPanel uiInfo = new JPanel(new GridLayout(2, 1));
uiInfo.setBorder(new EmptyBorder(0, 5, 0, 0));
uiInfo.setBackground(BACKGROUND_COLOR);
JShadowedLabel labelName = new JShadowedLabel(item.getDefinition().getName());
labelName.setForeground(Color.WHITE);
labelName.setVerticalAlignment(SwingUtilities.BOTTOM);
labelValue = new JShadowedLabel();
labelValue.setFont(FontManager.getRunescapeSmallFont());
labelValue.setVerticalAlignment(SwingUtilities.TOP);
updateXp(xp);
uiInfo.add(labelName);
uiInfo.add(labelValue);
// Settings Button
JLabel settingsButton = new JLabel();
settingsButton.setBorder(new EmptyBorder(0, 5, 0, 5));
settingsButton.setIcon(new ImageIcon(ICON_SETTINGS));
settingsButton.setOpaque(true);
settingsButton.setBackground(BACKGROUND_COLOR);
settingsButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseEntered(MouseEvent e)
{
settingsButton.setBackground(BUTTON_HOVER_COLOR);
}
@Override
public void mouseExited(MouseEvent e)
{
settingsButton.setBackground(BACKGROUND_COLOR);
}
@Override
public void mouseClicked(MouseEvent e)
{
toggleInfo();
}
});
// Create and append elements to container panel
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.setBackground(BACKGROUND_COLOR);
panel.add(image, BorderLayout.LINE_START);
panel.add(uiInfo, BorderLayout.CENTER);
// Only add button if has activity selection options or linked items
List<Activity> activities = Activity.getByCriticalItem(item);
// If linked map has 1 item and it isn't this item still show breakdown (cleaned herbs into unfinished)
if ((linkedMap.size() > 1 || (linkedMap.size() == 1 && linkedMap.get(item) == null))
|| activities.size() > 1)
{
panel.add(settingsButton, BorderLayout.LINE_END);
}
panel.setToolTipText("<html>" + item.getDefinition().getName()
+ "<br/>xp: " + xp
+ "<br/>Total: " + StackFormatter.quantityToStackSize((long) total) + "</html");
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.gridx = 0;
c.gridy = 0;
c.ipady = 20;
this.add(panel, c);
c.gridy++;
this.add(infoContainer, c);
}
private void toggleInfo()
{
infoVisibility = !infoVisibility;
if (infoVisibility)
{
createInfoPanel();
}
else
{
infoContainer.removeAll();
infoContainer.setVisible(false);
infoContainer.revalidate();
infoContainer.repaint();
}
}
private void createInfoPanel()
{
infoContainer.removeAll();
infoContainer.setVisible(true);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.gridx = 0;
c.gridy = 0;
c.ipady = 0;
JPanel p = createActivitiesPanel();
if (p != null)
{
infoContainer.add(p, c);
c.gridy++;
}
// Show linked item breakdown, including own items
if (linkedMap.size() > 1 || (linkedMap.size() == 1 && linkedMap.get(item) == null))
{
JLabel l = new JLabel("Item Breakdown");
l.setBorder(new EmptyBorder(3, 0, 3, 0));
l.setHorizontalAlignment(JLabel.CENTER);
infoContainer.add(l, c);
c.gridy++;
JPanel con = new JPanel();
con.setLayout(new GridBagLayout());
con.setBackground(BACKGROUND_COLOR);
for (Map.Entry<CriticalItem, Integer> e : linkedMap.entrySet())
{
// Icon
AsyncBufferedImage icon = itemManager.getImage(e.getKey().getItemID(), e.getValue(), e.getKey().getDefinition().isStackable() || e.getValue() > 1);
JLabel image = new JLabel();
image.setMinimumSize(ICON_SIZE);
image.setMaximumSize(ICON_SIZE);
image.setPreferredSize(ICON_SIZE);
image.setHorizontalAlignment(SwingConstants.CENTER);
image.setBorder(new EmptyBorder(0, 8, 0, 0));
Runnable resize = () ->
image.setIcon(new ImageIcon(icon.getScaledInstance((int) ICON_SIZE.getWidth(), (int) ICON_SIZE.getHeight(), Image.SCALE_SMOOTH)));
icon.onChanged(resize);
resize.run();
image.setToolTipText(e.getKey().getDefinition().getName());
con.add(image, c);
c.gridx++;
}
c.gridx = 0;
infoContainer.add(con, c);
}
}
private JPanel createActivitiesPanel()
{
List<Activity> activities = Activity.getByCriticalItem(item);
if (activities == null || activities.size() == 1)
{
return null;
}
JPanel p = new JPanel();
p.setBackground(BACKGROUND_COLOR);
p.setLayout(new BorderLayout());
JLabel label = new JLabel("Possible training methods");
MaterialTabGroup group = new MaterialTabGroup();
group.setLayout(new GridLayout(0, 6, 0, 2));
group.setBorder(new MatteBorder(1, 1, 1, 1, Color.BLACK));
Activity selected = this.bankedCalculator.getSelectedActivity(this.item);
boolean s = false;
for (Activity option : activities)
{
AsyncBufferedImage icon = itemManager.getImage(option.getIcon());
MaterialTab matTab = new MaterialTab("", group, null);
matTab.setHorizontalAlignment(SwingUtilities.RIGHT);
matTab.setToolTipText(option.getName());
Runnable resize = () ->
matTab.setIcon(new ImageIcon(icon.getScaledInstance(24, 24, Image.SCALE_SMOOTH)));
icon.onChanged(resize);
resize.run();
group.addTab(matTab);
// Select first option by default
if (!s)
{
s = true;
group.select(matTab);
}
// Select the option if its their selected activity
if (option.equals(selected))
{
group.select(matTab);
}
// Add click event handler now to prevent above code from triggering it.
matTab.setOnSelectEvent(() ->
{
bankedCalculator.activitySelected(item, option);
return true;
});
}
p.add(label, BorderLayout.NORTH);
p.add(group, BorderLayout.SOUTH);
return p;
}
public void updateXp(double newXpRate)
{
xp = newXpRate;
total = xp * amount;
labelValue.setText(FORMAT_COMMA.format(total) + "xp");
}
public void updateAmount(int newAmount, boolean forceVisible)
{
this.setVisible(newAmount > 0 || forceVisible);
this.amount = newAmount;
AsyncBufferedImage icon = itemManager.getImage(item.getItemID(), amount, item.getDefinition().isStackable() || amount > 1);
Runnable resize = () ->
image.setIcon(new ImageIcon(icon.getScaledInstance((int) ICON_SIZE.getWidth(), (int) ICON_SIZE.getHeight(), Image.SCALE_SMOOTH)));
icon.onChanged(resize);
resize.run();
}
public void updateLinkedMap(Map<CriticalItem, Integer> newLinkedMap)
{
this.linkedMap = newLinkedMap;
int sum = 0;
for (Integer v : newLinkedMap.values())
{
sum += v;
}
this.updateAmount(sum, false);
this.updateXp(xp);
// Refresh info panel if visible
if (infoVisibility)
{
createInfoPanel();
}
}
public void recalculate()
{
updateXp(xp);
}
}

View File

@@ -24,10 +24,9 @@
*/
package net.runelite.client.plugins.skillcalculator.beans;
import lombok.AccessLevel;
import lombok.Getter;
@Getter(AccessLevel.PUBLIC)
@Getter
public class SkillData
{
private SkillDataEntry[] actions;

View File

@@ -24,10 +24,9 @@
*/
package net.runelite.client.plugins.skillcalculator.beans;
import lombok.AccessLevel;
import lombok.Getter;
@Getter(AccessLevel.PUBLIC)
@Getter
public class SkillDataBonus
{
private String name;

View File

@@ -24,10 +24,9 @@
*/
package net.runelite.client.plugins.skillcalculator.beans;
import lombok.AccessLevel;
import lombok.Getter;
@Getter(AccessLevel.PUBLIC)
@Getter
public class SkillDataEntry
{
private String name;

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2019, TheStonedTurtle <http://www.github.com/TheStonedTurtle>
* 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.ui.components;
import javax.annotation.Nullable;
import javax.swing.Icon;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* Used with ComboBoxListRenderer to render an icon next to the text of the list entry.
* Also supports adding a data object to be used for more complex selection logic
*/
@AllArgsConstructor
@Getter
public class ComboBoxIconEntry
{
private Icon icon;
private String text;
@Nullable
private Object data;
}

View File

@@ -30,6 +30,7 @@ import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.border.EmptyBorder;
import lombok.Setter;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.util.Text;
@@ -41,6 +42,8 @@ import net.runelite.client.util.Text;
*/
public final class ComboBoxListRenderer extends JLabel implements ListCellRenderer
{
@Setter
private String defaultText = "Select an option...";
@Override
public Component getListCellRendererComponent(JList list, Object o, int index, boolean isSelected, boolean cellHasFocus)
@@ -57,12 +60,24 @@ public final class ComboBoxListRenderer extends JLabel implements ListCellRender
}
setBorder(new EmptyBorder(5, 5, 5, 0));
setIcon(null);
String text;
if (o instanceof Enum)
// If using setSelectedItem(null) or setSelectedIndex(-1) show default text until a selection is made
if (index == -1 && o == null)
{
text = defaultText;
}
else if (o instanceof Enum)
{
text = Text.titleCase((Enum) o);
}
else if (o instanceof ComboBoxIconEntry)
{
ComboBoxIconEntry e = (ComboBoxIconEntry) o;
text = e.getText();
setIcon(e.getIcon());
}
else
{
text = o.toString();