Jump to content
View in the app

A better way to browse. Learn more.

OSBot :: 2007 OSRS Botting

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Best method to look for grounditems dropped only by monsters you kill

Featured Replies

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.

  • Author

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.

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.

  • Author
On 12/30/2018 at 8:29 PM, liverare said:

I'm guessing this is for ironmen? :)

More-so just don't want to run around picking up everyone's arrows :D

  • Author
        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.

Create an account or sign in to comment

Recently Browsing 0

  • No registered users viewing this page.

Account

Navigation

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.