scriptersteve Posted January 27, 2018 Share Posted January 27, 2018 (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 January 27, 2018 by scriptersteve Quote Link to comment Share on other sites More sharing options...
Explv Posted January 27, 2018 Share Posted January 27, 2018 (edited) On 1/27/2018 at 2:18 PM, 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 Expand .contains(), .getAmount() and .interact() all accept a Filter<Item>: inventory.contains(item -> item.getName().endsWith(" arrow")) Edited January 27, 2018 by Explv Quote Link to comment Share on other sites More sharing options...
scriptersteve Posted January 27, 2018 Author Share Posted January 27, 2018 oh so i need to define the filter inside the contains and not outside and then call the item? Quote Link to comment Share on other sites More sharing options...
scriptersteve Posted January 27, 2018 Author Share Posted January 27, 2018 On 1/27/2018 at 2:27 PM, Explv said: .contains(), .getAmount() and .interact() all accept a Filter<Item>: inventory.contains(item -> item.getName().endsWith(" arrow")) Expand 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) Quote Link to comment Share on other sites More sharing options...
HunterRS Posted January 27, 2018 Share Posted January 27, 2018 (edited) On 1/27/2018 at 2:36 PM, 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) Expand 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 January 27, 2018 by HunterRS Quote Link to comment Share on other sites More sharing options...
scriptersteve Posted January 27, 2018 Author Share Posted January 27, 2018 OK will look into that Quote Link to comment Share on other sites More sharing options...
Butters Posted January 27, 2018 Share Posted January 27, 2018 (edited) On 1/27/2018 at 2:49 PM, scriptersteve said: OK will look into that Expand 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 January 27, 2018 by nosepicker Quote Link to comment Share on other sites More sharing options...
scriptersteve Posted January 27, 2018 Author Share Posted January 27, 2018 On 1/27/2018 at 3:09 PM, 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); Expand 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? Quote Link to comment Share on other sites More sharing options...
Butters Posted January 27, 2018 Share Posted January 27, 2018 On 1/27/2018 at 4:23 PM, 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? Expand 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. Quote Link to comment Share on other sites More sharing options...
scriptersteve Posted January 27, 2018 Author Share Posted January 27, 2018 oh okay thanks - so like if my script is called goblins i just put golbins in there - thanks mate it helps alot Quote Link to comment Share on other sites More sharing options...
Butters Posted January 27, 2018 Share Posted January 27, 2018 On 1/27/2018 at 4:41 PM, scriptersteve said: oh okay thanks - so like if my script is called goblins i just put golbins in there - thanks mate it helps alot Expand 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); 1 Quote Link to comment Share on other sites More sharing options...
liverare Posted January 27, 2018 Share Posted January 27, 2018 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. 1 Quote Link to comment Share on other sites More sharing options...
scriptersteve Posted January 27, 2018 Author Share Posted January 27, 2018 On 1/27/2018 at 11:28 PM, 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. Expand Thanks, i actually understand everything you just wrote :') 1 Quote Link to comment Share on other sites More sharing options...
HeyImJamie Posted January 27, 2018 Share Posted January 27, 2018 On 1/27/2018 at 11:28 PM, 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. Expand 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 Quote Link to comment Share on other sites More sharing options...
The Undefeated Posted January 28, 2018 Share Posted January 28, 2018 On 1/27/2018 at 11:50 PM, 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 Expand 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. 1 Quote Link to comment Share on other sites More sharing options...