Camaro Posted December 30, 2018 Share Posted December 30, 2018 Consider the following scenario: You are killing monsters around other players who are killing the same monsters with iron arrows. You want to loot the iron arrows dropped by your monsters, but not pick up any other iron arrows on the ground. What is the best way to achieve this? I have written some code, but not sure if this is efficient... if (myPlayer().getInteracting() != null && Timing.waitCondition(() -> myPlayer().getInteracting().getHealthPercent() == 0, 5000)) { LAST_KILL = myPlayer().getInteracting().getPosition(); } else if (!getCombat().isFighting()) { GroundItem item = getGroundItems().closest(g -> g != null && getMap().canReach(g) && (g.getName().equals("Iron arrow") && g.getAmount() > 4 && g.getPosition().equals(LAST_KILL))); if (item != null) { int count = (int) inventory.getAmount(item.getName()); if (item.interact("Take")) { Timing.waitCondition(() -> inventory.getAmount(item.getName()) > count, 3000); } } } Once the monster's health percent, I store that monsters position to a variable. Then I make sure that the ground item's position is the same as the stored position. Quote Link to comment Share on other sites More sharing options...
Camaro Posted December 30, 2018 Author Share Posted December 30, 2018 Seem to be having better luck with this if (myPlayer().getInteracting() != null) { CURR_KILL = myPlayer().getInteracting(); List<GroundItem> items = getGroundItems().get(CURR_KILL.getX(), CURR_KILL.getY()); items.removeIf(i -> !i.getName().equals("Bones")); if (Timing.waitCondition(() -> { List<GroundItem> items2 = getGroundItems().get(CURR_KILL.getX(), CURR_KILL.getY()); items2.removeIf(i -> !i.getName().equals("Bones")); return items.size() < items2.size(); }, 10000)) { GroundItem item = getGroundItems().closest(g -> g != null && getMap().canReach(g) && (g.getName().equals("Iron arrow") && g.getAmount() > 4 && g.getPosition().equals(CURR_KILL.getPosition()))); if (item != null) { int count = (int) inventory.getAmount(item.getName()); if (item.interact("Take")) { Timing.waitCondition(() -> inventory.getAmount(item.getName()) > count, 3000); } } } } If the player is interacting (fighting) with something, wait until their bones drop. then scan for items. Quote Link to comment Share on other sites More sharing options...
Script Kid Posted December 30, 2018 Share Posted December 30, 2018 ur code looks retard dont want to read it Quote Link to comment Share on other sites More sharing options...
liverare Posted December 31, 2018 Share Posted December 31, 2018 I'm guessing this is for ironmen? The key for this would be to not only look for loot where the monster was killed, but to also go through the items you want 1-by-1 to check whether you can loot it, and to remove it from the list if you can't. import java.util.LinkedList; import java.util.stream.Collectors; import java.util.stream.Stream; import org.osbot.rs07.api.map.Position; import org.osbot.rs07.api.model.GroundItem; import org.osbot.rs07.api.model.NPC; import org.osbot.rs07.script.Script; import org.osbot.rs07.utility.ConditionalSleep; public class test extends Script { NPC target; Position targetTile; LinkedList<GroundItem> loot; GroundItem nextLoot; @Override public int onLoop() throws InterruptedException { target = npcs.closest("Something..."); targetTile = target.getPosition(); { // once target is dead loot(); } return 0; } private void loot() { if (loot == null) { // let's find some loot loot = getGroundItems(targetTile, "Iron arrows", "Bronze arrows", "Bone bolts"); } else if (loot.isEmpty()) { // can't loot anything else loot = null; } else if (nextLoot != null && nextLoot.exists()) { // next loot ready for the taking if (takeItem(nextLoot)) { // check inventory to make sure we picked it up... // tally up a counter.... // price check..... // etc...... } nextLoot = null; } else { // need to get the next loot in the queue nextLoot = loot.poll(); } } private boolean takeItem(GroundItem item) { boolean taken = false; ConditionalSleep sleepyTimesUntilWePickupItem; if (item != null && item.exists()) { sleepyTimesUntilWePickupItem = new ConditionalSleep(2500) { @Override public boolean condition() throws InterruptedException { // item exists in memory, but not in game return item != null && !item.exists(); } }; if (item.interact("Take")) { taken = sleepyTimesUntilWePickupItem.sleep(); // assume we picked it up } } return taken; } private LinkedList<GroundItem> getGroundItems(Position tile, String... names) { return groundItems.get(tile.getX(), tile.getY()) .stream() .filter(item -> Stream.of(names).anyMatch(item.getName()::equalsIgnoreCase)) .collect(Collectors.toCollection(LinkedList<GroundItem>::new)); } } Untested btw. 1 Quote Link to comment Share on other sites More sharing options...
Camaro Posted January 1, 2019 Author Share Posted January 1, 2019 On 12/31/2018 at 1:29 AM, liverare said: I'm guessing this is for ironmen? Expand More-so just don't want to run around picking up everyone's arrows Quote Link to comment Share on other sites More sharing options...
Camaro Posted January 1, 2019 Author Share Posted January 1, 2019 if ((CURR_KILL = myPlayer().getInteracting()) != null) { if (CURR_KILL.getHealthPercent() == 0) { List<GroundItem> items = getGroundItems().get(CURR_KILL.getX(), CURR_KILL.getY()); items.removeIf(i -> !i.getName().equals("Bones")); if (Timing.waitCondition(() -> { List<GroundItem> items2 = getGroundItems().get(CURR_KILL.getX(), CURR_KILL.getY()); items2.removeIf(i -> !i.getName().equals("Bones")); return items.size() < items2.size(); }, 5000)) { GroundItem item = getGroundItems().closest(g -> g != null && getMap().canReach(g) && (g.getName().equals("Iron arrow") && g.getPosition().equals(CURR_KILL.getPosition()))); if (item != null) { int count = (int) inventory.getAmount(item.getName()); if (item.interact("Take")) Timing.waitCondition(() -> inventory.getAmount(item.getName()) > count, 3000); } } } } Believe I have perfected this... Keep looping until the monster I am interacting with has zero health. Then save it's position and wait for the bones to appear. Then loot any arrows with that monsters position. Quote Link to comment Share on other sites More sharing options...