dragon40226 Posted May 29, 2018 Share Posted May 29, 2018 (edited) Wanted to Share something that I took from TriBot, and then ported to here. Inventory Listener watches everything that comes in and out of the Inventory. This is useful for tracking how many Logs Cut or Ores Mined and whatever else you need. 1. Interfaces Needed (Condition and InventoryListener). Condition.java : @FunctionalInterface public interface Condition { /** * Tracks if the Condition is active or not * @return boolean of whether its active or not */ boolean active(); } InventoryListener.java : public interface InventoryListener { /** * When a new item comes into the Inventory, this is invoked. * @param item ID of item gained * @param count amount of item gained */ void inventoryItemGained(int item, int count); /** * When a new item goes out of the Inventory, this is invoked. * @param item ID of item lost * @param count amount of item lost */ void inventoryItemLost(int item, int count); } InventoryObserver.java : import xobot.script.methods.tabs.Inventory; import xobot.script.util.Time; import xobot.script.wrappers.interactive.Item; import java.util.ArrayList; import java.util.HashMap; /** * Watches the inventory (for items coming in and going out) * Threaded, so it doesnt hog resources */ public class InventoryObserver extends Thread { private ArrayList<InventoryListener> listeners; private Condition condition; public InventoryObserver(Condition condition) { this.listeners = new ArrayList<>(); this.condition = condition; } /** * Main Logic */ @Override public void run() { //Item, Amount HashMap<Integer, Integer> map = inventoryHashMap(); while (true) { Time.sleep(100); if (!condition.active()) { map = inventoryHashMap(); continue; } HashMap<Integer, Integer> updatedMap = inventoryHashMap(); for (int item : updatedMap.keySet()) { int countInitial = map.getOrDefault(item, 0), countFinal = updatedMap.get(item); if (countFinal > countInitial) { addTrigger(item, countFinal - countInitial); } else if (countFinal < countInitial) { subtractedTrigger(item, countInitial - countFinal); } map.remove(item); } for (Integer i : map.keySet()) if (!updatedMap.containsKey(i)) subtractedTrigger(i, map.get(i)); map = updatedMap; } } /** * Create new hashmap of current Inventory * @return the inventoryHashMap */ private HashMap<Integer, Integer> inventoryHashMap() { HashMap<Integer, Integer> map = new HashMap<>(); for (Item item : Inventory.getItems()) { map.put(item.getID(), item.getStack()); } return map; } /** * Adds listener to the list * @param inventoryListener listener to add */ public void addListener(InventoryListener inventoryListener) { this.listeners.add(inventoryListener); } /** * Trigger invoked when an item is added to the inventory, procs all listeners * @param item ID of item that came in * @param amount amount of item that came in */ private void addTrigger(int item, int amount) { for (InventoryListener l : listeners) l.inventoryItemGained(item, amount); } /** * Trigger invoked when an item left the inventory, procs all listeners * @param item ID of item that left * @param amount amount of item that left */ private void subtractedTrigger(int item, int amount) { for (InventoryListener l : listeners) l.inventoryItemLost(item, amount); } } That was the Needed Code to implement. Here is a basic implementation of how it can be used: import xobot.script.ActiveScript; import xobot.script.methods.Bank; public class DragonLooter extends ActiveScript implements InventoryListener{ private InventoryObserver inventoryObserver; private int goldFoundOnFloor; @Override public boolean onStart() { //Don't watch what goes into Inventory when Bank is open inventoryObserver = new InventoryObserver(() -> !Bank.isOpen()); inventoryObserver.addListener(this); inventoryObserver.start(); goldFoundOnFloor = 0; return true; } @Override public int loop() { return 0; } @Override public void onStop() { super.onStop(); //Stop the Thread inventoryObserver.interrupt(); } @Override public void inventoryItemGained(int item, int count) { if (item == 995) {// ID of GP goldFoundOnFloor += count; System.out.printf("Just Found %d coins on the floor\n", count); } } //Use the same idea as above @Override public void inventoryItemLost(int item, int count) { } } Hope it helps someone, Thanks! - Dragon Edited June 4, 2018 by dragon40226 Fixed stack cases 2 Link to comment Share on other sites More sharing options...
Jake Posted May 29, 2018 Share Posted May 29, 2018 Nice contribution (and welcome to xobot!). My only change would be to implement the runnable interface instead of extending from the thread class. Thanks Link to comment Share on other sites More sharing options...
dragon40226 Posted June 4, 2018 Author Share Posted June 4, 2018 Found a bug, wouldn't work for items that stack, fixed. should be: "map.put(item.getID(), item.getStack());" Link to comment Share on other sites More sharing options...
xBear Posted June 10, 2018 Share Posted June 10, 2018 Already posted this in Discord, but I'm looting bones and it only adds 1. Link to comment Share on other sites More sharing options...
Recommended Posts