Jump to content

Differentiating between chests


guseggers

Recommended Posts

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!

Link to comment
Share on other sites

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

 

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. 

Link to comment
Share on other sites

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

 

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.

  • Like 1
Link to comment
Share on other sites

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 by Lemons
  • Like 4
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

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

Edited by Bobrocket
Link to comment
Share on other sites

Don't forget that you can replace stream() with parallelStream() to multithread the operation smile.png

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

 

That null check should be unneeded as I don't think they return nulls in the list.

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