Jump to content

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


Recommended Posts

Posted

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");
    }

 

Posted (edited)
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
Posted
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

  • Like 1
Posted
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

Posted
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

Posted (edited)
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
  • Like 2
Posted
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

Posted
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.

Posted
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.

Posted (edited)

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
  • Like 1
Posted
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.

  • Like 2
Posted

@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. 

 

  • Like 2
  • Boge 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...