October 7, 20178 yr 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, 20178 yr by Deathiminent fixed bug
November 28, 20178 yr 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.
Create an account or sign in to comment