yfoo Posted September 13, 2018 Share Posted September 13, 2018 (edited) Snippit takes in 2 item objects or item id, randomly picks an item slot, checks if it is one of the item parameters, then uses BFS to find the corresponding item to combine with. The usage of BFS is because when it finds its goal, it is guarenteed to be the shortest path (or 1 of), therefore bfs in this case will find 2 inv slot indicies that are close to each other. Like how you would do item combination in osrs if you actually had to do it. This is an alternative to using the default; item1.interact("use") on item2.interact("use") because by default the 2 inventory items select is always the first occurance of those items. IDK if item interaction indicies are tracked by Jagex but this is a way to ofuscate any data collection on that matter. You recieve a int[2] where the 2 items are the inventory slot indicies to use on each other. There is no guarentee that int[0] is always item1 and int[1] is always item2. If you have that use case, modify my code; hint: modify the method: int[] bfsItemCombinationSlots(Item[] invItems, int item1ID, int item2ID) Because of the above stipulation, you also do not need to have code that selects the item at slot int[0] and interact with the item at slot int[1] if you wanted to randomize if you selected item 1 first or item 2 first. My code does that for you. Common Use cases: combining a herblore ingredient with a unf potion making unf potions combining a bowstring with an unstrung bow combining clay with water charged orb with battlestaff ect... Code: public int[] bfsItemCombinationSlots(Item[] invItems, Item item1, Item item2){ return bfsItemCombinationSlots(invItems, item1.getId(), item2.getId()); } private int[] bfsItemCombinationSlots(Item[] invItems, int item1ID, int item2ID){ int startIdx = ThreadLocalRandom.current().nextInt(10, 18); int otherIdx = -1; if(invItems[startIdx] != null){ //find what item occupies invItems[startIdx] and bfs with the target being the corresponding item if(invItems[startIdx].getId() == item1ID){ otherIdx = bfsTargetItemSlotHelper(invItems, item2ID, startIdx); } else if(invItems[startIdx].getId() == item2ID){ otherIdx = bfsTargetItemSlotHelper(invItems, item1ID, startIdx); } //error check if(otherIdx != -1) return new int[]{startIdx, otherIdx}; } //Some error occurred. invItems[startIdx] may be null or is an item that is not item1 or item2. Recommend doing normal inventory combine. return new int[]{-1, -1}; } private int bfsTargetItemSlotHelper(Item[] invItems, int targetItemID, int startingInvIdx){ if(startingInvIdx < 0 || startingInvIdx > 27){ throw new UnsupportedOperationException("input needs to in range [0-27]."); } Queue<Integer> bfsQ = new LinkedList<>(); boolean[] visitedSlots = new boolean[28]; bfsQ.add(startingInvIdx); visitedSlots[startingInvIdx] = true; while(!bfsQ.isEmpty()){ int current = bfsQ.poll(); if(invItems[current].getId() == targetItemID){ return current; } List<Integer> successors = getSuccessors(current); successors.forEach(slot -> { if(!visitedSlots[slot]){ visitedSlots[slot] = true; bfsQ.add(slot); } }); } return -1; } private List<Integer> getSuccessors(int invSlot) { List<Integer> successors = new ArrayList<>(); boolean canUp = false, canRight = false, canDown = false, canLeft = false; if(!(invSlot <= 3)){ //up, cannot search up if invSlot is top 4 slots successors.add(invSlot - 4); canUp = true; } if((invSlot + 1) % 4 != 0){ //right, cannot search right if invSlot is rightmost column successors.add(invSlot + 1); canRight = true; } if(!(invSlot >= 24)){ //down, cannot search down if invSlot is bottom 4 slots successors.add(invSlot + 4); canDown = true; } if(invSlot % 4 != 0){ //left, cannot search left if invSlot is leftmost column successors.add(invSlot - 1); canLeft = true; } //can search in diagonal directions if can search in its composite directions if(canUp && canRight){ successors.add(invSlot - 3); } if(canUp && canLeft){ successors.add(invSlot - 5); } if(canDown && canRight){ successors.add(invSlot + 5); } if(canDown && canLeft){ successors.add(invSlot + 3); } Collections.shuffle(successors); //randomize search order at the same search depth. return successors; } Usage: private boolean combineComponents() throws InterruptedException { Inventory inv = script.getInventory(); int[] slots = bfsItemCombinationSlots(inv.getItems(),recipe.getPrimaryItemID(), recipe.getSecondaryItemID()); //ensure algorithm did not fail. If you any other items in inventory or empty spaces, code may return {-1, -1} //if such happens, use a regular combination interaction if(slots[0] != -1 && slots[1] != -1){ if(inv.interact(slots[0], USE)){ MethodProvider.sleep(Statics.randomNormalDist(300,100)); return inv.isItemSelected() && inv.interact(slots[1], USE); } } else { if(inv.interact(USE, recipe.getPrimaryItemID())){ MethodProvider.sleep(Statics.randomNormalDist(300,100)); return inv.isItemSelected() && inv.interact(USE, recipe.getSecondaryItemID()); } } return false; } Edited September 13, 2018 by PayPalMeRSGP 1 Quote Link to comment Share on other sites More sharing options...
Naked Posted September 13, 2018 Share Posted September 13, 2018 Nice! I'll have to look into using this for a few things. Wasn't sure how to implement something like this. 1 Quote Link to comment Share on other sites More sharing options...