guseggers Posted October 19, 2015 Share Posted October 19, 2015 package natRune; import java.awt.Graphics2D; import java.util.concurrent.TimeUnit; import org.osbot.rs07.api.model.Entity; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; @ScriptManifest(author = "", info = "Ardougne", name = "Ardougne Stealer", version = 0.01, logo = "") public class natRune extends Script { private long timeBegan; private long timeRan; @Override public void onStart() { log("Welcome to 's script!"); log("If you find any bugs or have any suggestions, please contact me!"); timeBegan = System.currentTimeMillis(); } @Override public void onExit() { log("Thanks for using 's script!"); } private enum State { WAIT, SEARCH }; private State getState() { Entity chest = objects.closest("Chest"); if (chest != null) return State.SEARCH; return State.WAIT; } public void onPaint(Graphics2D g) { Graphics2D gr = g; timeRan = System.currentTimeMillis() - this.timeBegan; g.drawString(ft(timeRan), 10, 320); } private String ft(long duration) { String res = ""; long days = TimeUnit.MILLISECONDS.toDays(duration); long hours = TimeUnit.MILLISECONDS.toHours(duration) - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration)); long minutes = TimeUnit.MILLISECONDS.toMinutes(duration) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration)); long seconds = TimeUnit.MILLISECONDS.toSeconds(duration) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration)); if (days == 0) { res = (hours + ":" + minutes + ":" + seconds); } else { res = (days + ":" + hours + ":" + minutes + ":" + seconds); } return res; } @Override public int onLoop() throws InterruptedException { switch (getState()) { case SEARCH: Entity chest = objects.closest("Chest"); if (chest != null) { chest.interact("Search for traps"); } case WAIT: sleep(random(15713, 17913)); break; } return random(201, 319); } } Hi! This is one of my first scripts, so I thought I'd keep it simple. It is by the chests where you steal 1 nat and 3gp in Ardougne. There are two chests up there, but my script just has it to interact with the nearest chest. Is there any way to loot one even if your closer to another? - Another idea. Could I have it so it interacts with one chest, follows a walkPath command to the other chest, loots it, and bank? Any help is appreciated! Quote Link to comment Share on other sites More sharing options...
LoudPacks Posted October 19, 2015 Share Posted October 19, 2015 (edited) You can use a filter. I made a script very similar to this which also alches the looted nats. Heres an example using filters, although i prefer to use lambas rather than the traditional way of filtering: chest = getObjects().closest(o -> o.getPosition().equals(new Position(2671, 3301, 1))); // filters out every entity that's not at the specified position (ie. chest 2) if(chest.interact("Search for traps")){ log("Attempting to loot chest..."); new ConditionalSleep(15500, 17550){ @Override public boolean condition() throws InterruptedException { int start = getSkills().getExperience(Skill.THIEVING); return ((getSkills().getExperience(Skill.THIEVING) > start) || wasLooted); } }.sleep(); // I have a method that wasLooted that uses game messages to see if its already looted and then the wait time is adjusted accordingly Edited October 19, 2015 by LoudPacks Quote Link to comment Share on other sites More sharing options...
Bobrocket Posted October 20, 2015 Share Posted October 20, 2015 You can use a filter. I made a script very similar to this which also alches the looted nats. Heres an example using filters, although i prefer to use lambas rather than the traditional way of filtering: chest = getObjects().closest(o -> o.getPosition().equals(new Position(2671, 3301, 1))); // filters out every entity that's not at the specified position (ie. chest 2) if(chest.interact("Search for traps")){ log("Attempting to loot chest..."); new ConditionalSleep(15500, 17550){ @Override public boolean condition() throws InterruptedException { int start = getSkills().getExperience(Skill.THIEVING); return ((getSkills().getExperience(Skill.THIEVING) > start) || wasLooted); } }.sleep(); // I have a method that wasLooted that uses game messages to see if its already looted and then the wait time is adjusted accordingly Your conditional sleep won't work, because it calls condition() which means it will reset start every time. Quote Link to comment Share on other sites More sharing options...
Explv Posted October 20, 2015 Share Posted October 20, 2015 (edited) You could use the IDs of the different chests, although this might break if the IDs ever change. Or yes use Loud packs technique, where you just create two positions, one for each Chest, and interact with the chest in the relevant position: Without the use of a filter, to loot "Chest 1" would look like: Position chest1 = new Position(x, x, x); for ( RS2Object obj : getObjects() ){ if (obj.getPosition() == chest1 ){ obj.interact(); break; } } Or with a filter: getObjects().closest(o -> o.getPosition().equals(new Position(x, x, x))).interact(); Edited October 20, 2015 by Explv Quote Link to comment Share on other sites More sharing options...
Woody Posted October 20, 2015 Share Posted October 20, 2015 You could use the IDs of the different chests, although this might break if the IDs ever change. Or yes use Loud packs technique, where you just create two positions, one for each Chest, and interact with the chest in the relevant position: Without the use of a filter, to loot "Chest 1" would look like: Position chest1 = new Position(x, x, x); for ( RS2Object obj : getObjects() ){ if (obj.getPosition() == chest1 ){ obj.interact(); break; } } Or with a filter: getObjects().closest(o -> o.getPosition().equals(new Position(x, x, x))).interact(); I would strongly recommend using filter. Getting all objects is unnecessary and not so efficient. 1 Quote Link to comment Share on other sites More sharing options...
Lemons Posted October 20, 2015 Share Posted October 20, 2015 (edited) I would strongly recommend using filter. Getting all objects is unnecessary and not so efficient. filter will go through all the items in the list just like a loop will, unless its async it shouldn't perform significantly better. I do agree filters are much cleaner code though. Also, without using a 3rd party API you can use filter like: getObjects().getAll().stream().filter(o -> o.exists()).findFirst() Its not as pretty but it works! Edit: Fixed derp typo lol Edited October 20, 2015 by Lemons 4 Quote Link to comment Share on other sites More sharing options...
LoudPacks Posted October 20, 2015 Share Posted October 20, 2015 Your conditional sleep won't work, because it calls condition() which means it will reset start every time. Oh shit your right, it doesnt even do anything now that I think about it. It does work for my needs since wasLooted is still in the return. I should remove the xp tho because your right its useless and even if it worked that would be the condition that should initiate the waiting LOL Quote Link to comment Share on other sites More sharing options...
Explv Posted October 20, 2015 Share Posted October 20, 2015 (edited) I would strongly recommend using filter. Getting all objects is unnecessary and not so efficient. So would I if you want it to look nice, just trying to show its more commonly understood alternative Edited October 20, 2015 by Explv Quote Link to comment Share on other sites More sharing options...
Bobrocket Posted October 20, 2015 Share Posted October 20, 2015 (edited) filter will go through all the items in the list just like a loop will, unless its async it shouldn't perform significantly better. I do agree filters are much cleaner code though. Also, without using a 3rd party API you can use filter like: getObjects().getAll().stream().filter(o -> o.exists()).findFirst() Its not as pretty but it works! Edit: Fixed derp typo lol Don't forget that you can replace stream() with parallelStream() to multithread the operation Streams can be used for a lot of cooler things, if you want to learn some more things to do with streams as well as learning the full syntax visit here: http://osbot.org/forum/topic/81691-basic-streams-and-how-to-use-them/ The full stream would look a little like this: Entity chest = getObjects().getAll().stream().filter((o) -> (o != null && o.exists() && o.getName().equals("Chest") && o.getPosition().equals(new Position(x, y, z)))).findFirst().orElse(null); On the off chance that you're using OmniAPI (shameless self plug because fuck you), you can just use: Entity chest = getEntityFinder().findClosest("Chest", (entity) -> (entity.getPosition().equals(new Position(x, y, z)))); OmniAPI uses streams in its finders too Edited October 20, 2015 by Bobrocket Quote Link to comment Share on other sites More sharing options...
Lemons Posted October 20, 2015 Share Posted October 20, 2015 Don't forget that you can replace stream() with parallelStream() to multithread the operation Streams can be used for a lot of cooler things, if you want to learn some more things to do with streams as well as learning the full syntax visit here: http://osbot.org/forum/topic/81691-basic-streams-and-how-to-use-them/ The full stream would look a little like this: Entity chest = getObjects().getAll().stream().filter((o) -> (o != null && o.exists() && o.getName().equals("Chest") && o.getPosition().equals(new Position(x, y, z)))).findFirst().orElse(null); On the off chance that you're using OmniAPI (shameless self plug because fuck you), you can just use: Entity chest = getEntityFinder().findClosest("Chest", (entity) -> (entity.getPosition().equals(new Position(x, y, z)))); OmniAPI uses streams in its finders too That null check should be unneeded as I don't think they return nulls in the list. Quote Link to comment Share on other sites More sharing options...