Deathimminent Posted October 7, 2017 Share Posted October 7, 2017 (edited) Feedback is welcome. This class allows you to easily create setups for your inventory, gear, or whatever, and check if you have those items. I mainly created this class to create setups where you can just specify items to add and it match for a range of charges or doses for the same item. Example: you want to match a glory with a charge of (1), (2), (3). Instead of doing if (item.getId() == 1 || item.getId() == 1 || item.getId() == 3) You would add the item to List<RequiredItem> reqItems reqItems.add(new RequiredItem("Amulet of glory (1), 1, 3); when you call ItemRequirement.getMissingItems(Item[] items) it will match at least one Amulet of glory(1), (2), and (3). I didn't bother making an actual script for demonstration, but maybe this will make the usage clearer: Spoiler import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import test.ItemRequirement.RequiredItem; @ScriptManifest(author = "", info = "", logo = "", name = "Test", version = 0.1) public class Test extends Script { List<RequiredItem> invItemsForNewTrip = new ArrayList<>(); List<RequiredItem> invItemsForThreshold = new ArrayList<>(); List<RequiredItem> gearItems = new ArrayList<>(); ItemRequirement invSetupForNewTrip; ItemRequirement invSetupForThreshold; ItemRequirement gearSetup; @Override public void onStart() { // add 3 dueling rings with accepted charges 6-8 invItemsForNewTrip.add(new RequiredItem("Ring of dueling(6)", 3, 2)); // add 5 salmon invItemsForNewTrip.add(new RequiredItem("Salmon", 5)); // add a rope invItemsForNewTrip.add(new RequiredItem("Rope")); // add a chair invItemsForNewTrip.add(new RequiredItem("Chair")); // create the inventory setup for a new trip invSetupForNewTrip = new ItemRequirement(invItemsForNewTrip); invItemsForThreshold.add(new RequiredItem("Salmon", 1)); invSetupForThreshold = new ItemRequirement(invItemsForThreshold); gearItems.add(new RequiredItem("Adamant scimitar")); // add a glory with only (2) as the accepted charge gearItems.add(new RequiredItem("Amulet of glory(2)")); gearSetup = new ItemRequirement(gearItems); } @Override public int onLoop() throws InterruptedException { HashMap<String, Integer> missingInvItems = invSetupForNewTrip.getMissingItems(getInventory().getItems()); if (missingInvItems.size() > 0) { // bank and withdraw missing items } else { // do something else } missingInvItems = invSetupForThreshold.getMissingItems(getInventory().getItems()); // if missingInvItems is > 0, meaning we don't have at least 1 salmon if (missingInvItems.size() > 0) { // tele away } else { // don't tele away } HashMap<String, Integer> missingGearItems = gearSetup.getMissingItems(getEquipment().getItems()); if (missingGearItems.size() > 0) { // do whatever you would do if you are missing gear } else { // do whatever you would do if you aren't missing any gear } return 500; } Source: Spoiler import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; import org.osbot.rs07.api.model.Item; public class ItemRequirement { private List<RequiredItem> items; public ItemRequirement(List<RequiredItem> items) { this.items = items; } /** * If an item to check for has a charge or dose is in its name, e.g. Ring of * dueling(4), it will also check for the item with additional * charges/doses, up to the value of RequiredItem's range field. * <p> * Example: item is Ring of dueling(4) with a range of 3 * will match Ring of dueling(4), (5), (6), and (7) * * @param itemsToCheck the items to check against * * @return a map of the missing items in (item name : missing amount) pairs. * If no items are missing the map will be empty. */ public HashMap<String, Integer> getMissingItems(Item[] itemsToCheck) { HashMap<String, Integer> missingItems = new HashMap<>(); List<Item> itemList = Arrays.asList(itemsToCheck); // list rep. of items to check against for (RequiredItem itemToCheck : this.items) { int desiredAmount = itemToCheck.getAmount(); int minCharge = getItemCharge(itemToCheck.getName()); int maxCharge = minCharge + itemToCheck.getRange(); List<Item> filteredList; String name = removeCharge(itemToCheck.getName()); // filtered list to match noted items if (itemToCheck.isNoted()) { filteredList = itemList.stream() .filter(i -> (i != null && removeCharge(i.getName()).toLowerCase().equals(name.toLowerCase()) && i.isNote())) .collect(Collectors.toList()); } else { // not matching noted items filteredList = itemList.stream() .filter(i -> (i != null && removeCharge(i.getName()).toLowerCase().equals(name.toLowerCase()) && !i.isNote())) .collect(Collectors.toList()); } // if we have at least one matching item if (filteredList.size() > 0) { // if the item we're checking for contains a charge/dose, check to // see if we have an item with that charge/dose, up to (starting charge/dose + range) if (minCharge > 0) { int itemCount = 0; // keep track of how many items we have for (Item t_item : filteredList) { int itemCharge = getItemCharge(t_item.getName()); if (itemCharge >= minCharge && itemCharge <= maxCharge) { if (itemToCheck.isNoted()) { // we're only checking for noted items if (t_item.isNote()) { itemCount += t_item.getAmount(); } } else { itemCount += t_item.getAmount(); } } } // add to list the missing amount of items if (itemCount < desiredAmount) { missingItems.put(itemToCheck.getName(), desiredAmount - itemCount); } } else { // item has no charge, so we check for exact item name int currentAmount = 0; // the item is stackable or we only have 1 occurrence, so get the amount if (filteredList.size() == 1) { currentAmount = filteredList.get(0).getAmount(); } else { // we have more than 1 occurrence, so the item probably isn't stackable currentAmount = filteredList.size(); } // if insufficient amount, add to list the item // and the missing amount if (currentAmount < desiredAmount) { missingItems.put(itemToCheck.getName(), desiredAmount - currentAmount); } } } else // we don't have the item if (desiredAmount > 0) { missingItems.put(itemToCheck.getName(), desiredAmount); } } return missingItems; } public String getMissingItemsMessage(HashMap<String, Integer> missingItems) { String message = ""; for (String s : missingItems.keySet()) { message = message + "Missing Item: " + s + " | Quantity: " + missingItems.get(s) + "\n"; } return message; } /** * @param item the item's name * * @return the number of charges/doses the item has. Returns 0 if no * charge/dose. */ private int getItemCharge(String item) { int openIndex = item.indexOf("("); int closeIndex = item.indexOf(")"); int charge = 0; if (openIndex != -1 && closeIndex != -1) { try { charge = Integer.parseInt(item.substring(openIndex + 1, closeIndex)); } catch (NumberFormatException e) { } } return charge; } private String removeCharge(String name) { if (name.contains("(")) { return name.substring(0, name.indexOf("(")); } return name; } public static class RequiredItem { private String name; private int amount; private int range; private boolean noted; /** * Represents a required, single, un-noted item matching only this * charge/dose, if it has one. * * @param name the name of the item */ public RequiredItem(String name) { this(name, 1, 0, false); } /** * Represents a required, un-noted item, of at least the specified quantity, * matching only this charge/dose, if it has one. * * @param name the name of the item * @param amount the amount of the item */ public RequiredItem(String name, int amount) { this(name, amount, 0, false); } /** * Represents a required, un-noted item, of at least the specified quantity, * matching this item's charge/dose, if it has one, up to an additional * value of the range. * * @param name the name of the item * @param amount the amount of the item * @param range the additional charges/doses to accept */ public RequiredItem(String name, int amount, int range) { this(name, amount, range, false); } /** * Represents a required, noted item, of at least the specified quantity, * matching this item's charge/dose, if it has one, up to an additional * value of the range. * * @param name the name of the item * @param amount the amount of the item * @param range the additional charges/doses to accept * @param noted whether or not the item is noted */ public RequiredItem(String name, int amount, int range, boolean noted) { this.name = name; this.amount = amount; this.range = range; this.noted = noted; } public String getName() { return name; } public int getAmount() { return amount; } public int getRange() { return range; } public boolean isNoted() { return noted; } } } Edited October 10, 2017 by Deathiminent fixed bug 3 Quote Link to comment Share on other sites More sharing options...
Deceiver Posted October 7, 2017 Share Posted October 7, 2017 will save me time, thanks:) Quote Link to comment Share on other sites More sharing options...
Pertinate Posted November 28, 2017 Share Posted November 28, 2017 I seem to be getting a bug with the ring of dueling. According to what you say the code below "should" work. gearItems.add(new RequiredItem("Ring of dueling(1)", 1, 7)); But it doesn't detect any other charges besides whatever the initial value is. Quote Link to comment Share on other sites More sharing options...