From a2afc8d65d9817a9b0750c68189f5fddd881314c Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Wed, 10 Jul 2019 19:18:45 +0200 Subject: [PATCH] skillcalc: New UI and panel --- .../skillcalculator/BankedCalculator.java | 675 ------------- .../skillcalculator/CacheSkillData.java | 2 +- .../skillcalculator/CalculatorType.java | 54 +- .../skillcalculator/SkillCalculator.java | 68 +- .../SkillCalculatorConfig.java | 18 +- .../skillcalculator/SkillCalculatorPanel.java | 163 +--- .../SkillCalculatorPlugin.java | 158 ++-- .../plugins/skillcalculator/UIActionSlot.java | 4 +- .../UICalculatorInputArea.java | 21 +- .../skillcalculator/UICombinedActionSlot.java | 6 +- .../banked/BankedCalculator.java | 462 +++++++++ .../banked/BankedCalculatorPanel.java | 120 +++ .../skillcalculator/banked/CriticalItem.java | 418 --------- .../banked/beans/Activity.java | 885 ++++++++++++------ .../banked/beans/ActivitySecondaries.java | 112 --- .../banked/beans/BankedItem.java | 53 ++ .../banked/beans/CriticalItem.java | 355 +++++++ .../{SecondaryItem.java => ItemInfo.java} | 28 +- .../banked/beans/ItemStack.java | 36 + .../banked/beans/Secondaries.java | 118 +++ .../banked/beans/XpModifiers.java | 64 ++ .../banked/components/GridItem.java | 201 ++++ .../banked/components/ModifyPanel.java | 354 +++++++ .../banked/components/SelectionGrid.java | 142 +++ .../banked/ui/CriticalItemPanel.java | 402 -------- .../skillcalculator/beans/SkillData.java | 3 +- .../skillcalculator/beans/SkillDataBonus.java | 3 +- .../skillcalculator/beans/SkillDataEntry.java | 3 +- .../ui/components/ComboBoxIconEntry.java | 44 + .../ui/components/ComboBoxListRenderer.java | 17 +- 30 files changed, 2708 insertions(+), 2281 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/BankedCalculator.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/BankedCalculator.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/BankedCalculatorPanel.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/CriticalItem.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/ActivitySecondaries.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/BankedItem.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/CriticalItem.java rename runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/{SecondaryItem.java => ItemInfo.java} (80%) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/ItemStack.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/Secondaries.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/XpModifiers.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/components/GridItem.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/components/ModifyPanel.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/components/SelectionGrid.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/ui/CriticalItemPanel.java create mode 100644 runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxIconEntry.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/BankedCalculator.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/BankedCalculator.java deleted file mode 100644 index ac7d985013..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/BankedCalculator.java +++ /dev/null @@ -1,675 +0,0 @@ -/* - * Copyright (c) 2018, 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 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 bankMap = new HashMap<>(); - private final Map categoryMap = new HashMap<>(); // Check if CriticalItem Category is enabled - private final Map panelMap = new HashMap<>(); - private final Map criticalMap = new HashMap<>(); // Quantity of CriticalItem inside bankMap - private final Map activityMap = new HashMap<>(); // Selected Activity used for calculating xp - private final Map 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("
Banked Experience is not enabled for this skill.
", 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 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 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 map = getBankedXpBreakdown(); - for (Map.Entry 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 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 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 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 getBankedXpBreakdown() - { - Map map = new LinkedHashMap<>(); - - for (String category : CriticalItem.getSkillCategories(currentSkill)) - { - List 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 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 getLinkedTotalMap(CriticalItem i, boolean first) - { - Map 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 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(); - } -} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/CacheSkillData.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/CacheSkillData.java index a427b602ac..f4f54e0f52 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/CacheSkillData.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/CacheSkillData.java @@ -35,7 +35,7 @@ class CacheSkillData { private final Map cache = new HashMap<>(); - SkillData getSkillData(final String dataFile) + SkillData getSkillData(String dataFile) { if (cache.containsKey(dataFile)) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/CalculatorType.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/CalculatorType.java index 8874563113..e102988f50 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/CalculatorType.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/CalculatorType.java @@ -1,6 +1,5 @@ /* * Copyright (c) 2018, Kruithne - * Copyright (c) 2018, 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; - } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculator.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculator.java index e0b614a95a..4434aa92fd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculator.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculator.java @@ -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 uiActionSlots = new ArrayList<>(); private final CacheSkillData cacheSkillData = new CacheSkillData(); - @Getter(AccessLevel.PACKAGE) private final UICombinedActionSlot combinedActionSlot; - @Getter(AccessLevel.PACKAGE) private final List combinedActionSlots = new ArrayList<>(); private final List 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) - *

- * 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(); - } - }); - } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorConfig.java index 9fd11ba13f..825c620459 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorConfig.java @@ -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; } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorPanel.java index 79684db069..b6abe4577f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorPanel.java @@ -1,7 +1,6 @@ /* * Copyright (c) 2018, Kruithne * Copyright (c) 2018, Psikoi - * Copyright (c) 2018, 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 tabs = new ArrayList<>(); - @Getter - private Map 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 bank) - { - bankMap = bank; - if (currentCalc != null & currentTab.equals("Banked Xp")) - { - bankedCalculator.updateBankMap(bankMap); - } - } - - void updateSkillCalculator(Skill skill) - { - uiCalculator.updateSkillCalculator(skill); - } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorPlugin.java index e6a5316cf3..147420e7b1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorPlugin.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2018, Kruithne - * Copyright (c) 2018, TheStonedTurtle + * Copyright (c) 2019, 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 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 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 getBankMapIfDiff(Item[] widgetItems) - { - Map mapCheck = new HashMap<>(); + final Map 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()); } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UIActionSlot.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UIActionSlot.java index 819e75ad4b..2051a0ddcd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UIActionSlot.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UIActionSlot.java @@ -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); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICalculatorInputArea.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICalculatorInputArea.java index 515b3997d0..6584c85bf9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICalculatorInputArea.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICalculatorInputArea.java @@ -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(); } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICombinedActionSlot.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICombinedActionSlot.java index f84cdecb23..fa1614c91b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICombinedActionSlot.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/UICombinedActionSlot.java @@ -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); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/BankedCalculator.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/BankedCalculator.java new file mode 100644 index 0000000000..821fd23fc4 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/BankedCalculator.java @@ -0,0 +1,462 @@ +/* + * Copyright (c) 2019, 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 linkedMap = ArrayListMultimap.create(); + + private final Map bankedItemMap = new LinkedHashMap<>(); + private final JLabel totalXpLabel = new JLabel(); + private final ModifyPanel modifyPanel; + private SelectionGrid itemGrid; + + @Setter + private Map bankMap = new HashMap<>(); + + @Getter + private Skill currentSkill; + + @Getter + private int skillLevel, skillExp, endLevel, endExp; + + private final Collection 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 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 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 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 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 createLinksMap(final BankedItem item) + { + final Map qtyMap = new HashMap<>(); + + final Activity a = item.getItem().getSelectedActivity(); + if (a == null) + { + return qtyMap; + } + + final Collection 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(); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/BankedCalculatorPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/BankedCalculatorPanel.java new file mode 100644 index 0000000000..f017040e2a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/BankedCalculatorPanel.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2019, 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 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 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 bankMap) + { + calculator.setBankMap(bankMap); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/CriticalItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/CriticalItem.java deleted file mode 100644 index 983526c59a..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/CriticalItem.java +++ /dev/null @@ -1,418 +0,0 @@ -/* - * Copyright (c) 2018, 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> buildSkillItemMap() - { - Map> map = new HashMap<>(); - for (CriticalItem item : values()) - { - map.computeIfAbsent(item.getSkill(), e -> new ArrayList<>()).add(item); - } - - return map; - } - - private static final Map> bySkillName = buildSkillItemMap(); - - public static List getBySkillName(Skill skill) - { - return bySkillName.get(skill); - } - - // Builds a Map to reduce looping frequency - private static Map> buildSkillCategoryMap() - { - Map> map = new HashMap<>(); - for (CriticalItem item : values()) - { - map.computeIfAbsent(item.getSkill(), k -> new HashSet<>()).add(item.category); - } - - return map; - } - - private static final Map> bySkillCategory = buildSkillCategoryMap(); - - public static Set getSkillCategories(Skill skill) - { - return bySkillCategory.get(skill); - } - - // Builds a Map to reduce looping frequency - private static Map> buildItemSkillCategoryMap() - { - Map> 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> itemsBySkillCategory = buildItemSkillCategoryMap(); - - public static List getItemsForSkillCategories(Skill skill, String category) - { - return itemsBySkillCategory.get(category + skill.getName()); - } - - // Builds a Map to reduce looping frequency - private static Map buildItemsByIdMap() - { - Map map = new HashMap<>(); - for (CriticalItem item : values()) - { - map.put(item.getItemID(), item); - } - - return map; - } - - private static final Map 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 + ")"; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/Activity.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/Activity.java index 080dad9cb9..16aee82217 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/Activity.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/Activity.java @@ -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 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> buildItemMap() - { - Map> map = new HashMap<>(); - for (Activity item : values()) + final ImmutableMultimap.Builder 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> byCriticalItem = buildItemMap(); - - public static List 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 getByCriticalItem(CriticalItem item, int limitLevel) + public static List getByCriticalItem(CriticalItem item) { - List activities = getByCriticalItem(item); - List l = new ArrayList<>(); + final Collection 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 getByCriticalItem(final CriticalItem item, final int limitLevel) + { + // Return as list to allow getting by index + final List 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()); + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/ActivitySecondaries.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/ActivitySecondaries.java deleted file mode 100644 index 0afb3cf033..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/ActivitySecondaries.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2018, 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; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/BankedItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/BankedItem.java new file mode 100644 index 0000000000..5256d26351 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/BankedItem.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018, 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; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/CriticalItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/CriticalItem.java new file mode 100644 index 0000000000..d6f3752742 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/CriticalItem.java @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2018, 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_MAP = ArrayListMultimap.create(); + private static final Map 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 getBySkill(Skill skill) + { + Collection 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()); + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/SecondaryItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/ItemInfo.java similarity index 80% rename from runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/SecondaryItem.java rename to runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/ItemInfo.java index 0cc728d0f9..8bc3651ed9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/SecondaryItem.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/ItemInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, TheStonedTurtle + * Copyright (c) 2019, 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; +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/ItemStack.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/ItemStack.java new file mode 100644 index 0000000000..3b785f4020 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/ItemStack.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019, 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; +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/Secondaries.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/Secondaries.java new file mode 100644 index 0000000000..cab6b7474f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/Secondaries.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2018, 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; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/XpModifiers.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/XpModifiers.java new file mode 100644 index 0000000000..b9fcae99c6 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/beans/XpModifiers.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2019, 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 MODIFIERS_MAP; + + static + { + final ImmutableMultimap.Builder map = ImmutableMultimap.builder(); + for (final XpModifiers m : values()) + { + map.put(m.skill, m); + } + MODIFIERS_MAP = map.build(); + } + + public static Collection getModifiersBySkill(final Skill skill) + { + return MODIFIERS_MAP.get(skill); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/components/GridItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/components/GridItem.java new file mode 100644 index 0000000000..9cb03ff36b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/components/GridItem.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2019, 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 = "" + bankedItem.getItem().getItemInfo().getName(); + + final Activity a = bankedItem.getItem().getSelectedActivity(); + if (a != null) + { + final double xp = parent.getCalc().getItemXpRate(bankedItem); + tip += "
Activity: " + a.getName(); + tip += "
Xp/Action: " + BankedCalculator.XP_FORMAT_COMMA.format(xp); + tip += "
Total Xp: " + BankedCalculator.XP_FORMAT_COMMA.format(xp * amount); + } + else + { + tip += "
Outputs: " + bankedItem.getItem().getItemInfo().getName(); + } + + return tip + ""; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/components/ModifyPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/components/ModifyPanel.java new file mode 100644 index 0000000000..c111789377 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/components/ModifyPanel.java @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2018, 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 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(""); + b.append(bankedItem.getQty()).append(" x ").append(bankedItem.getItem().getItemInfo().getName()); + + for (final Map.Entry e : this.linkedMap.entrySet()) + { + b.append("
").append(e.getValue()).append(" x ").append(e.getKey().getItemInfo().getName()); + } + + b.append(""); + 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("" + itemName + + "
xp: " + xp + + "
Total: " + total + " 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 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; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/components/SelectionGrid.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/components/SelectionGrid.java new file mode 100644 index 0000000000..2449857920 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/components/SelectionGrid.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2018, 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 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 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 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(); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/ui/CriticalItemPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/ui/CriticalItemPanel.java deleted file mode 100644 index 1b12419ec0..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/banked/ui/CriticalItemPanel.java +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright (c) 2018, 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 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 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 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("" + item.getDefinition().getName() - + "
xp: " + xp - + "
Total: " + StackFormatter.quantityToStackSize((long) total) + " 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 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 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 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); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/beans/SkillData.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/beans/SkillData.java index 0d5b1cad40..4c2d36aa68 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/beans/SkillData.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/beans/SkillData.java @@ -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; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/beans/SkillDataBonus.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/beans/SkillDataBonus.java index 6cce75a62e..675fcb51db 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/beans/SkillDataBonus.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/beans/SkillDataBonus.java @@ -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; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/beans/SkillDataEntry.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/beans/SkillDataEntry.java index 05ec9c878a..b21188d913 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/beans/SkillDataEntry.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/beans/SkillDataEntry.java @@ -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; diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxIconEntry.java b/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxIconEntry.java new file mode 100644 index 0000000000..7c94851bc9 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxIconEntry.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019, 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; +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxListRenderer.java b/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxListRenderer.java index 5aeb710115..907170f412 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxListRenderer.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/ComboBoxListRenderer.java @@ -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();