Aqla Posted August 14, 2022 Share Posted August 14, 2022 (edited) Hello all. I'm writing a fighter bot that picks up loot from the tile where the last target died. I was wondering if someone could point me to a more efficient and clean way to write the for loops that check for relevant items on the tile and picks them up (see below). Looking forward to learn more. public void lootingLastKilled() { List<GroundItem> itemsOnTile = getGroundItems().get(targetTile.getX(), targetTile.getY()); List<String> itemsToLoot = Stream.of("Feather","Bones").collect(Collectors.toList()); // Check for items on target tile that match items the bot should loot for (int i = 0; i < itemsOnTile.size(); i++) { for (int j = 0; j < itemsToLoot.size(); j++) { if (itemsOnTile.get(i).getName().equals(itemsToLoot.get(j))) { // Pick up ground item that matches items to loot GroundItem itemToPickUp = itemsOnTile.get(i); itemToPickUp.interact("Take"); (new ConditionalSleep(3000) { public boolean condition() throws InterruptedException { return myPlayer().isAnimating(); } }).sleep(); } } } } Edited August 14, 2022 by Aqla 1 Quote Link to comment Share on other sites More sharing options...
Khaleesi Posted August 14, 2022 Share Posted August 14, 2022 (edited) private boolean lootItems(Position targetPosition) { List<String> itemsToLoot = Stream.of("Feather", "Bones").collect(Collectors.toList()); GroundItem itemToLoot = getGroundItems().closest(item -> item.getPosition().equals(targetPosition) && itemsToLoot.contains(item.getName())); if (itemToLoot != null) { if (itemToLoot.interact("Take")) { Timing.waitCondition(() -> !itemToLoot.exists(), 5_000); } return true; } return false; } Pick them up 1 by 1, returns true when loot is found Edited August 14, 2022 by Khaleesi 1 Quote Link to comment Share on other sites More sharing options...
Chris Posted August 14, 2022 Share Posted August 14, 2022 8 hours ago, Aqla said: Hello all. I'm writing a fighter bot that picks up loot from the tile where the last target died. I was wondering if someone could point me to a more efficient and clean way to write the for loops that check for relevant items on the tile and picks them up (see below). Looking forward to learn more. List<String> itemsToLoot = Stream.of("Feather", "Bones").collect(Collectors.toList()); // Use streams to filter out anything not in our itemsToLoot and create a new collection. List<GroundItem> itemsOnTile = getGroundItems().get(targetTile.getX(), targetTile.getY()).stream() .filter(g -> g != null && itemsToLoot.contains(g.getName())) .collect(Collectors.toList()); // Check if there is anything available. if (!itemsOnTile.isEmpty()) { // We have items on this tile matching our filter. // Start looting. (Below is just a for each loop) for (GroundItem groundItem : itemsOnTile) { // Always null check when dealing with the OSBot api it will save you in the long run. if (groundItem != null && groundItem.interact("Take")) { new ConditionalSleep(3000) { @Override public boolean condition() throws InterruptedException { // item doesnt exist OR our players position is on the current tile (faster looting ig) return !groundItem.exists() || myPosition().equals(groundItem.getPosition()); } }.sleep(); } } } Added some comments but lmk if u need to understand something 1 1 Quote Link to comment Share on other sites More sharing options...
Aqla Posted August 15, 2022 Author Share Posted August 15, 2022 17 hours ago, Khaleesi said: Pick them up 1 by 1, returns true when loot is found Thank you, Khal! 10 hours ago, Chris said: Added some comments but lmk if u need to understand something Thank you so much, Chris! This helped me a great deal and taught me a lot. One step closer to writing great scripts. Really appreciate you putting time into the comments and syntax clarification. 2 Quote Link to comment Share on other sites More sharing options...