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.

Interacting with 2 of Same Item in Inv w/o Slots

Featured Replies

Basically, I am trying to use an item on another item with the same name in my inventory. Normally, I could just use slots to distinguish between the two, but the problem in this script is that it is not predetermined where the item will be.

I tried using the code below. It works well when there is two different items as the first and second Item in the list. But, when they are the same item, it just clicks on the first item twice. I thought when you created a list of Items using a string, that it would be location specific as well. However, it seems to only get the name.

My second thought was just to make a second list with the additional filter for itemIsSelected. But, then after thinking about it, the same thing will still happen if it just grabs the name.

Any ideas? I will give you credit for helping with this portion if I do release this script.

public void combineSpices(){
        String [] spiceColors ={"Red","Yellow","Brown","Orange"};
        for(String x:spiceColors){
            while(combinableSpices(x)>1){

                java.util.List<Item> vialsToCombine = Arrays.stream(getInventory().getItems()).filter(i -> i != null &&
                        i.nameContains(x+" spice (1)",x+" spice (2)",x+" spice (3)")).collect(Collectors.toList());
                vialsToCombine.get(0).interact("Use");
                vialsToCombine.get(1).interact("Use");
        }
        }
        inventory.dropAll("Empty spice shaker");
    }

 

Why not select the first item and just interact with the second?

 

if no item selected

select first item

else

use on other item

  • Author
16 minutes ago, Juggles said:

Why not select the first item and just interact with the second?

 

if no item selected

select first item

else

use on other item

Well that's what I am trying to do. The problem is that I can't distinguish the two items when they have the same names. All of the methods in the API (interact, getSlot, etc) always grab the "first item" matching an id or string. So what I really need is a way to output all of the slots for when there is more than one of the same item.

To clarify, my list contains all of the 1dose , 2dose , 3dose spices. It works great until it runs into the case of 2 of the same amount of doses because then they have the same name.

Edited by cooldoruk60

36 minutes ago, cooldoruk60 said:

Well that's what I am trying to do. The problem is that I can't distinguish the two items when they have the same names. All of the methods in the API (interact, getSlot, etc) always grab the "first item" matching an id or string. So what I really need is a way to output all of the slots for when there is more than one of the same item.

To clarify, my list contains all of the 1dose , 2dose , 3dose spices. It works great until it runs into the case of 2 of the same amount of doses because then they have the same name.

Oh I see what you mean.

I've done something similar with grabbing the second closest NPC. 

You can try to filter out the first item


Something like f->f.getName.equals(NAME) && f!=firstItem

I don't have my IDE so i can't test right now but you can try that

  • Author
3 minutes ago, Juggles said:

Oh I see what you mean.

I've done something similar with grabbing the second closest NPC. 

You can try to filter out the first item


Something like f->f.getName.equals(NAME) && f!=firstItem

I don't have my IDE so i can't test right now but you can try that

That's a good idea actually. It still won't be able to combine them if they have the same amount of doses, but at least I can skip them for now until I have a more permanent solution. Thanks

16 minutes ago, cooldoruk60 said:

That's a good idea actually. It still won't be able to combine them if they have the same amount of doses, but at least I can skip them for now until I have a more permanent solution. Thanks

 int firstItem = getInventory().getSlotForNameThatContains("");

Item secondItem = inventory.getItemInSlot(firstItem+1);

 secondItem.interact("Use");

This would work if the second item is always in the next slot or you knew what slot it was in after

 

Item first = null;
for (Item i : getInventory().getItems()) {
    if (satisfiesStuff(i)) {
        if (first != null) {
            first.use(i); //forgot wtf piece of the api it was again and can't be bothered to look it up
            break;
        } else {
            first = i;
        }
    }
}

 

43 minutes ago, dogetrix said:

 


Item first = null;
for (Item i : getInventory().getItems()) {
    if (satisfiesStuff(i)) {
        if (first != null) {
            first.use(i); //forgot wtf piece of the api it was again and can't be bothered to look it up
            break;
        } else {
            first = i;
        }
    }
}

 

Basically this^, but with slots instead of items, since Item does not contain slot data, if the 2 "different" items have the same name, it will still interact with the first occurence of the item twice.

Something like this maybe:
 

int[] slots = IntStream.range(0, Inventory.SIZE).filter(i -> isMatch(i, "Red spice")).toArray();
if(slots.length >= 2) {
	if(getInventory().interact(slots[0], "Use") && getInventory().isItemSelected()) {
		getInventory().interact(slots[1]);
	}
}

private boolean isMatch(int slot, String name) {
	Item item = getInventory().getItemInSlot(slot);
	return item != null && item.getName().startsWith(name) && !item.getName().endsWith("(4)");
}

 

Edited by FrostBug

  • Author
Quote
15 hours ago, FrostBug said:

Basically this^, but with slots instead of items, since Item does not contain slot data, if the 2 "different" items have the same name, it will still interact with the first occurence of the item twice.

Something like this maybe:
 



int[] slots = IntStream.range(0, Inventory.SIZE).filter(i -> isMatch(i, "Red spice")).toArray();
if(slots.length >= 2) {
	if(getInventory().interact(slots[0], "Use") && getInventory().isItemSelected()) {
		getInventory().interact(slots[1]);
	}
}

private boolean isMatch(int slot, String name) {
	Item item = getInventory().getItemInSlot(slot);
	return item != null && item.getName().startsWith(name) && !item.getName().endsWith("(4)");
}

 

 

Brilliant Frost! I believe this will work. Thanks

18 hours ago, FrostBug said:

Basically this^, but with slots instead of items, since Item does not contain slot data, if the 2 "different" items have the same name, it will still interact with the first occurence of the item twice

So if you have three items of the same type `getItems` will give you one object?

Or is it that when you interact with the item it automatically selects the first one in the inventory?

Either way it's dumb as hell. When you interact with an item you should expect to actually interact with that specific item.

  • Author
3 hours ago, dogetrix said:

So if you have three items of the same type `getItems` will give you one object?

Or is it that when you interact with the item it automatically selects the first one in the inventory?

Either way it's dumb as hell. When you interact with an item you should expect to actually interact with that specific item.

It's the second one. But yes it is dumb. I thought that by specifying an Item object, it would have the state of it's location as well. But, when you call it using methods like interact or getSlot, it grabs only the first item.

Following on from @FrostBug post, try this:
 

	@Override
	public int onLoop() throws InterruptedException {
		
		if (useItemWithAnotherItemOfTheSameName("Strength potion\\([1-3]\\)")) {
			stop(false);
		}
		
		return 250;
	}

	private boolean useItemWithAnotherItemOfTheSameName(String regex) {
		
		return IntStream.range(0, Inventory.SIZE)
			.filter(index -> {
				 Item item = inventory.getItemInSlot(index);
				 return item != null && item.getName().matches(regex);
			})
         	 	.limit(2)
			.allMatch(index -> inventory.interact(index, "Use"));
	}

Strength potion\\([1-3]\\) will match

  • Strength potion(1)
  • Strength potion(2)
  • Strength potion(3)

The \\ used for \\( and \\) allow us to 'escape' the ( and ) characters, because in regex, they're special characters that need escaping if you wish to use them literally. The [1-3] will match the numbers 1, 2 and 3.

Edited by liverare

1 hour ago, liverare said:

Following on from @FrostBug post, try this:
 


	@Override
	public int onLoop() throws InterruptedException {
		
		if (useItemWithAnotherItemOfTheSameName("Strength potion\\([1-3]\\)")) {
			stop(false);
		}
		
		return 250;
	}

	private boolean useItemWithAnotherItemOfTheSameName(String regex) {
		
		return IntStream.range(0, Inventory.SIZE)
			.filter(index -> {
				 Item item = inventory.getItemInSlot(index);
				 return item != null && item.getName().matches(regex);
			})
         	 	.limit(2)
			.allMatch(index -> inventory.interact(index, "Use"));
	}

Strength potion\\([1-3]\\) will match

  • Strength potion(1)
  • Strength potion(2)
  • Strength potion(3)

The \\ used for \\( and \\) allow us to 'escape' the ( and ) characters, because in regex, they're special characters that need escaping if you wish to use them literally. The [1-3] will match the numbers 1, 2 and 3.

You can use Pattern.quote to avoid having to worry about escape characters.

  • Author

@Juggles @FrostBug @liverare @dreameo

I used a combination of your guy's suggestions and I also ended up moving away from the interact in the api and basically making my own interact method with hover+click. It turned out incredible though. I took a vid so you guys can see how insanely fast it is lol. And it never messes up. Never using interact for inventory interactions again .Thanks for all the help guys! If this script gets approved, I'll credit you all in the post. 

 

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.