Jump to content

Item interacting better way?


Recommended Posts

Posted (edited)

 int a = getEquipment().getSlotForNameThatContains("arrow");
     Item  arrows2 = getEquipment().getItemInSlot(a);
//     if(inventory.contains(arrows2) && getInventory().getAmount(arrows2) > 500) {
  //       getInventory().interact("Equip", arrows2);

So I want to do something like above: make a filter for all possible arrow types that could be in inv and equip them once x amount are in the inventory. However due to inventory .contains and all other methods require a string input am struggling to see how this would work. 

I can get it to workin the following way but this is cumbersome and messy:

if (inventory.contains("Adamant arrow") & getInventory().getAmount("Adamant arrow") > 500) {
    getInventory().interact("Equip", "Adamant arrow");
} else if (inventory.contains("Mithril arrow") & getInventory().getAmount("Mithril arrow") > 500) {
    getInventory().interact("Equip", "Mithril arrow");
}else if(inventory.contains("Steel arrow") & getInventory().getAmount("Steel arrow") > 500) {
    getInventory().interact("Equip", "Steel arrow");
}else if(inventory.contains("Iron arrow") & getInventory().getAmount("Iron arrow") > 500) {
    getInventory().interact("Equip", "Iron arrow");
}else if(inventory.contains("Bronze arrow") & getInventory().getAmount("Bronze arrow") > 500) {
    getInventory().interact("Equip", "Bronze arrow");
}

Any feedback you have to improve my writing of situations like this would be appreciated

Edited by scriptersteve
Posted (edited)
9 minutes ago, scriptersteve said:

 int a = getEquipment().getSlotForNameThatContains("arrow");
     Item  arrows2 = getEquipment().getItemInSlot(a);
//     if(inventory.contains(arrows2) && getInventory().getAmount(arrows2) > 500) {
  //       getInventory().interact("Equip", arrows2);

So I want to do something like above: make a filter for all possible arrow types that could be in inv and equip them once x amount are in the inventory. However due to inventory .contains and all other methods require a string input am struggling to see how this would work. 

I can get it to workin the following way but this is cumbersome and messy:


if (inventory.contains("Adamant arrow") & getInventory().getAmount("Adamant arrow") > 500) {
    getInventory().interact("Equip", "Adamant arrow");
} else if (inventory.contains("Mithril arrow") & getInventory().getAmount("Mithril arrow") > 500) {
    getInventory().interact("Equip", "Mithril arrow");
}else if(inventory.contains("Steel arrow") & getInventory().getAmount("Steel arrow") > 500) {
    getInventory().interact("Equip", "Steel arrow");
}else if(inventory.contains("Iron arrow") & getInventory().getAmount("Iron arrow") > 500) {
    getInventory().interact("Equip", "Iron arrow");
}else if(inventory.contains("Bronze arrow") & getInventory().getAmount("Bronze arrow") > 500) {
    getInventory().interact("Equip", "Bronze arrow");
}

Any feedback you have to improve my writing of situations like this would be appreciated

.contains(), .getAmount() and .interact() all accept a Filter<Item>:

inventory.contains(item -> item.getName().endsWith(" arrow"))

 

Edited by Explv
Posted
11 minutes ago, Explv said:

.contains(), .getAmount() and .interact() all accept a Filter<Item>:


inventory.contains(item -> item.getName().endsWith(" arrow"))

 

if(inventory.contains(inventory.contains(item -> item.getName().endsWith(" arrow"))))
    if(getInventory().getAmount(inventory.contains(item -> item.getName().endsWith(" arrow"))) > 500) {
//       getInventory().interact("Equip", arrows2);

 

when i try the above the error i get on both getaount and contains is the following: cannot resolve method get amount (boolean)

Posted (edited)

 

8 minutes ago, scriptersteve said:

if(inventory.contains(inventory.contains(item -> item.getName().endsWith(" arrow"))))
    if(getInventory().getAmount(inventory.contains(item -> item.getName().endsWith(" arrow"))) > 500) {
//       getInventory().interact("Equip", arrows2);

 

when i try the above the error i get on both getaount and contains is the following: cannot resolve method get amount (boolean)

Look into 

import org.osbot.rs07.api.filter.Filter;

Edit:

also, you might want to look at what value's specifc functions return and what you are giving them. That might help shed some light on what you are doing wrong.

Edited by HunterRS
Posted (edited)
23 minutes ago, scriptersteve said:

OK will look into that :)

Could also create an enum, cause it's by nature meant to be a "classifier". Then just go through all the list at one go and no need for lenghty hardcoded if statements

enum Arrows {
		BRONZE_ARROW("Bronze arrow", 1, 50),
		IRON_ARROW("Iron arrow", 1, 50);
		// Etc, add more
		
		private String name;
		private int level;
		private int minimumAmount;
		
		private Arrows(String name, int level, int minimumAmount) {
			this.name = name;
			this.level = level;
			this.minimumAmount = minimumAmount;
		}
		
		public String getName() {
			return this.name();
		}
		
		public int getLevel() {
			return this.level;
		}
		
		public int getMinimumAmount() {
			return this.minimumAmount;
		}
	}
	
	public String getBestArrow(Script s) {
		Optional<Arrows> arrowOpt =  Arrays.asList(Arrows.values()).stream()
				// Only get those which you can wield
				.filter(f -> s.skills.getStatic(Skill.RANGED) >= f.getLevel())
				// Check if has in inventory
				.filter(f -> s.inventory.contains(f.getName()))
				// Check if has the minimum amount
				.filter(f -> s.inventory.getAmount(f.getName()) >= f.getMinimumAmount())
				// Sort in a descending order (last entries in enum first) returns best arrows first
				.sorted((m, n) -> n.ordinal() - m.ordinal())
				.findFirst();
		if (arrowOpt.isPresent())
			return arrowOpt.get().getName();
		return "";
	}

This should (didn't test it) find the best arrow you can equip if it's in inventory

Could use like this

String bestArrow = getBestArrow(/*param*/);
if (bestArrow != "")
	s.inventory.interact("Equip", bestArrow);

 

Edited by nosepicker
Posted
1 hour ago, nosepicker said:

Could also create an enum, cause it's by nature meant to be a "classifier". Then just go through all the list at one go and no need for lenghty hardcoded if statements


enum Arrows {
		BRONZE_ARROW("Bronze arrow", 1, 50),
		IRON_ARROW("Iron arrow", 1, 50);
		// Etc, add more
		
		private String name;
		private int level;
		private int minimumAmount;
		
		private Arrows(String name, int level, int minimumAmount) {
			this.name = name;
			this.level = level;
			this.minimumAmount = minimumAmount;
		}
		
		public String getName() {
			return this.name();
		}
		
		public int getLevel() {
			return this.level;
		}
		
		public int getMinimumAmount() {
			return this.minimumAmount;
		}
	}
	
	public String getBestArrow(Script s) {
		Optional<Arrows> arrowOpt =  Arrays.asList(Arrows.values()).stream()
				// Only get those which you can wield
				.filter(f -> s.skills.getStatic(Skill.RANGED) >= f.getLevel())
				// Check if has in inventory
				.filter(f -> s.inventory.contains(f.getName()))
				// Check if has the minimum amount
				.filter(f -> s.inventory.getAmount(f.getName()) >= f.getMinimumAmount())
				// Sort in a descending order (last entries in enum first) returns best arrows first
				.sorted((m, n) -> n.ordinal() - m.ordinal())
				.findFirst();
		if (arrowOpt.isPresent())
			return arrowOpt.get().getName();
		return "";
	}

This should (didn't test it) find the best arrow you can equip if it's in inventory

Could use like this


String bestArrow = getBestArrow(/*param*/);
if (bestArrow != "")
	s.inventory.interact("Equip", bestArrow);

 

Hey mate, thanks - i had a few queries to help me understand: in the String bestArrow = getBestArrow(param) what is the param part?

Also the streaming/ordinals part is not something i've come across - just read the Java api. But not quite sure how exactly it works - would you be able to explain a bit more? I dso get ordinal is kinda like position? but is that all it is?

Posted
1 minute ago, scriptersteve said:

Hey mate, thanks - i had a few queries to help me understand: in the String bestArrow = getBestArrow(param) what is the param part?

Also the streaming/ordinals part is not something i've come across - just read the Java api. But not quite sure how exactly it works - would you be able to explain a bit more? I dso get ordinal is kinda like position? but is that all it is?

just pass Script instance to getBestArrow(). It's your main script class (used to access inventory info and etc).

And Enum ordinal is the "position" of each element. So if you create an enum like

public enum Arrows {
BRONZE_ARROW, IRON_ARROW, STEEL_ARROW, MITHRIL_ARROW
}

bronze ordinal will be 0, iron will be 1, steel will be 2, mithril will be 3.

If your enum elements are ordered correctly, in this case, from worst arrow to best, then the higher ordinal()  value is returned - the better the arrow is.

Now for the stream sorted() method: It just sorts the values, in the this case,  in reverse order (from best to worst). So it calls ordinal() method to get which one is best and then sorts by that.

Posted
Just now, scriptersteve said:

oh okay thanks - so like if my script is called goblins i just put golbins in there - thanks mate it helps alot

If your main class is something like this

publi

public class Goblins extends Scripts {
  .. 
}

and you call getBestArrow inside this exact class then you need to do

getBestArrow(this);

 

  • Like 1
Posted

I wouldn't listen to what others have said, because from reading your code I can see you haven't quite grasped how loops work. You shouldn't be dabbling in enumerators, Lambda expressions, or even extending classes if you haven't figured out how to use loops. Also, be sure to separate chunks of logic into separate routines to make it easier to read and maintain:

public String getNextArrow() {
	
	String result = null;
	int arrowCount;
	
	String[] arrows = {
		"Adamant arrow",
		"Mithril arrow",
		"Steel arrow",
		"Iron arrow",
		"Bronze arrow"
	};

	for (String arrow : arrows) {
		
		arrowCount = getInventory().getAmount(arrow);
		
		if (arrowCount > 500) {
		
			result = arrow;
			break;
		}
	}
	
	return result;
}

public void equipArrows() {

	String nextArrow = getNextArrow();

	if (nextArrow != null) {
		
		getInventory().interact("Equip", nextArrow);
	}
}

Now there are reasons to use enumerators and Lambda expressions to really enhance what it is you're trying to achieve. But sometimes, simple = better.

  • Like 1
Posted
14 minutes ago, liverare said:

I wouldn't listen to what others have said, because from reading your code I can see you haven't quite grasped how loops work. You shouldn't be dabbling in enumerators, Lambda expressions, or even extending classes if you haven't figured out how to use loops. Also, be sure to separate chunks of logic into separate routines to make it easier to read and maintain:


public String getNextArrow() {
	
	String result = null;
	int arrowCount;
	
	String[] arrows = {
		"Adamant arrow",
		"Mithril arrow",
		"Steel arrow",
		"Iron arrow",
		"Bronze arrow"
	};

	for (String arrow : arrows) {
		
		arrowCount = getInventory().getAmount(arrow);
		
		if (arrowCount > 500) {
		
			result = arrow;
			break;
		}
	}
	
	return result;
}

public void equipArrows() {

	String nextArrow = getNextArrow();

	if (nextArrow != null) {
		
		getInventory().interact("Equip", nextArrow);
	}
}

Now there are reasons to use enumerators and Lambda expressions to really enhance what it is you're trying to achieve. But sometimes, simple = better.

Thanks, i actually understand everything you just wrote :')

  • Like 1
Posted
21 minutes ago, liverare said:

I wouldn't listen to what others have said, because from reading your code I can see you haven't quite grasped how loops work. You shouldn't be dabbling in enumerators, Lambda expressions, or even extending classes if you haven't figured out how to use loops. Also, be sure to separate chunks of logic into separate routines to make it easier to read and maintain:


public String getNextArrow() {
	
	String result = null;
	int arrowCount;
	
	String[] arrows = {
		"Adamant arrow",
		"Mithril arrow",
		"Steel arrow",
		"Iron arrow",
		"Bronze arrow"
	};

	for (String arrow : arrows) {
		
		arrowCount = getInventory().getAmount(arrow);
		
		if (arrowCount > 500) {
		
			result = arrow;
			break;
		}
	}
	
	return result;
}

public void equipArrows() {

	String nextArrow = getNextArrow();

	if (nextArrow != null) {
		
		getInventory().interact("Equip", nextArrow);
	}
}

Now there are reasons to use enumerators and Lambda expressions to really enhance what it is you're trying to achieve. But sometimes, simple = better.

How is spoonfeeding someone less simpler code any better than what others have done. He'll need to learn both Filters and Enums at some point :boge: 

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