Jump to content

ItemRequirement Class


Deathimminent

Recommended Posts

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 by Deathiminent
fixed bug
  • Like 3
Link to comment
Share on other sites

  • 1 month later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...