Jump to content

Item interacting better way?


scriptersteve

Recommended Posts


 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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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)

Link to comment
Share on other sites

 

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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: 

Link to comment
Share on other sites

11 minutes ago, HeyImJamie said:

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: 

It's not simple code if he can't even understand what he's doing/writing. Liverare's code is simpler and takes more lines to write but at least he understands what he's doing. 

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

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