Jump to content

RS2Object.interact() returns false


elemt

Recommended Posts

Hi again,

I have the following code for a simple powerminer that I'm making. It works and mines the first set of ores. After the ores respawn, my mineOre() method is invoked but the RS2Object.interact("Mine") returns false. Why is it working the first time and not the second?


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import org.osbot.rs07.api.filter.Filter;
import org.osbot.rs07.api.model.InteractableObject;
import org.osbot.rs07.api.model.RS2Object;
import org.osbot.rs07.api.ui.Message;
import org.osbot.rs07.script.Script;
import org.osbot.rs07.script.ScriptManifest;

@ScriptManifest(author = "Elemt", info = "Powermining", name = "PMiner", version = 1.0, logo = "")
public class PMine extends Script {

	private List<Map<String, Object>> rockDetailsList; // list of all rocks and whether they are mineable or not
	private int count; // keep track of ores mined
	private boolean canMine;
	
	private final String MINED_ORE = "You manage to mine some";
	

	@Override
	public void onStart() {
		count = 0;
		canMine = true;
		rockDetailsList = new ArrayList<Map<String,Object>>();
		setUpRockDetails(); // get surrounding rocks
	}
	
	
	@Override
	public int onLoop() throws InterruptedException {
		if(canMine) {
			mineOre();
		}
		return random(190,250);
	}

	
	/**
	 * Will allow mining once the ore is finished
	 */
	@Override
	public void onMessage(Message m) {
		if(m.getMessage().startsWith(MINED_ORE)) {
			count++;
			canMine = true;
		}
	}
	
	
	private boolean shouldDrop() {
		return count >= 2 && count % 2 == 0;
	}
	
	
	private void dropOre()
	{
		
	}
	
	
	private void mineOre() {
		for(final Map<String, Object> rockMap : rockDetailsList) {
			if((boolean) rockMap.get("mineable")) {
				RS2Object rock = (RS2Object) rockMap.get("rock");
				boolean interacted = rock.interact("Mine");
				log("Mining: " + interacted);
				rockMap.put("mineable", !interacted);
				canMine = false;
				TimerTask task = new TimerTask() {
					
					@Override
					public void run() {
						rockMap.put("mineable", true);
					}
				};
				new Timer().schedule(task, 7000);
				return;
			}
		}
	}
	
	
	/**
	 * This method will filter out objects and only return the rocks around the player's
	 * cardinal direction
	 * 
	 * @return A list containing a RS2Object around the player
	 */
	@SuppressWarnings("unchecked")
	private List<RS2Object> filterRocks() {
		return getObjects().filter(new Filter<RS2Object>()
		{
			@Override
			public boolean match(RS2Object v) {
				if(v instanceof InteractableObject) {
					if(v.getName().equals("Rocks")) {
						int myX = myPlayer().getX();
						int myY = myPlayer().getY();
						int rockX = v.getX();
						int rockY = v.getY();
						
						return (Math.abs(myX - rockX) == 1 && myY == rockY) || 
							   (Math.abs(myY - rockY) == 1 && myX == rockX);
					}
				}
				return false;
			}
		});
	}
	
	
	/**
	 * Sets up a List containing Maps which contain each rock as an RS2Object and a
	 * boolean that keeps track of whether an ore can be mined. 
	 */
	private void setUpRockDetails() {
		for(RS2Object rock : filterRocks()) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("rock", rock);
			map.put("mineable", true);
			this.rockDetailsList.add(map);
		}
	}
}
Edited by elemt
Link to comment
Share on other sites

Your caching all the rocks in the beginning, but never updating the cache. So your using an stale RS2Object that doesn't exist anymore, make it refresh the cache instead.

 

What do you mean by refreshing the cache? I added this to my code to put a new RS2Object in my list but it's still returning false for the interact() method. Once the TimerTask run() executes it should update the map key "rock" with a new rock.

private void mineOre() {
		for(final Map<String, Object> rockMap : rockDetailsList) {
			if((boolean) rockMap.get("mineable")) {
				final RS2Object rock = (RS2Object) rockMap.get("rock");
				boolean interacted = rock.interact("Mine");
				log("Mining: " + interacted);
				rockMap.put("mineable", !interacted);
				canMine = false;
				TimerTask task = new TimerTask() {
					@Override
					public void run() {
						int x = rock.getX();
						int y = rock.getY();
						List<RS2Object> objects = getObjects().get(x, y);
						for(RS2Object obj : objects) {
							if(obj.getName().equals("Rocks")) {
								rockMap.put("rock", obj);
								break;
							}
						}
						rockMap.put("mineable", true);
					}
				};
				new Timer().schedule(task, 6500);
				return;
			}
		}
	}
Link to comment
Share on other sites

What do you mean by refreshing the cache? I added this to my code to put a new RS2Object in my list but it's still returning false for the interact() method. Once the TimerTask run() executes it should update the map key "rock" with a new rock.

private void mineOre() {		for(final Map<String, Object> rockMap : rockDetailsList) {			if((boolean) rockMap.get("mineable")) {				final RS2Object rock = (RS2Object) rockMap.get("rock");				boolean interacted = rock.interact("Mine");				log("Mining: " + interacted);				rockMap.put("mineable", !interacted);				canMine = false;				TimerTask task = new TimerTask() {					@Override					public void run() {						int x = rock.getX();						int y = rock.getY();						List<RS2Object> objects = getObjects().get(x, y);						for(RS2Object obj : objects) {							if(obj.getName().equals("Rocks")) {								rockMap.put("rock", obj);								break;							}						}						rockMap.put("mineable", true);					}				};				new Timer().schedule(task, 6500);				return;			}		}	}

The idea is that when you mine the rock, the osrs client replaces the object with its depleted version meaning it is no longer there. You need to make sure they aren't null and that they have the actions Mine and Prospect so that they are valid rocks.

Link to comment
Share on other sites

sleep(random(350,450));
for(final Map<String, Object> rockMap : rockDetailsList) {
 

Well I added a sleep before checking if they're mineable and it works sometimes. I don't know why it doesn't every time

 

 

The problem is that when you mine a rock, The game object changes to an entirely different object; so next time you try to interact with the old instance of the game object, it no longer exists, and nothing happens.

 

Link to comment
Share on other sites

You save the current rock in an object.

Once this is mined another object will be placed and the old object doesn't exist anymore.

Last time I checked it's impossible to interact with something that doesn't exist smile.png

 

You'll have to update your rock list frequently to make sure you got the latest objects smile.png

 

(I tried to interact with my non existing girlfriend once before, unfortunately nothing happend... :'( Should have null checked her before ... -_- )

 

Khaleesi

Edited by Khaleesi
  • Like 2
Link to comment
Share on other sites

You save the current rock in an object.

Once this is mined another object will be placed and the old object doesn't exist anymore.

Last time I checked it's impossible to interact with something that doesn't exist smile.png

You'll have to update your rock list frequently to make sure you got the latest objects smile.png

(I tried to interact with my non existing girlfriend once before, unfortunately nothing happend... :'( Should have null checked her before ... -_- )

Khaleesi

Remember to perform instanceof Girl, because both Boy and Girl extend the abstract Person class :doge:

Link to comment
Share on other sites

A new boolean value; not a new RS2Object representing the rock. You have to use the filter again

 

 

I updated my run() method in a previous post. Here it is again. I am getting a new RS2Object

TimerTask task = new TimerTask() {
	@Override
	public void run() {
		int x = rock.getX();
		int y = rock.getY();
		List<RS2Object> objects = getObjects().get(x, y);
		for(RS2Object obj : objects) {
			if(obj.getName().equals("Rocks")) {
				log("get's here");
				rockMap.put("rock", obj);
				break;
			}
		}
		rockMap.put("mineable", true);
	}
};
Link to comment
Share on other sites

 

I updated my run() method in a previous post. Here it is again. I am getting a new RS2Object

TimerTask task = new TimerTask() {
	@Override
	public void run() {
		int x = rock.getX();
		int y = rock.getY();
		List<RS2Object> objects = getObjects().get(x, y);
		for(RS2Object obj : objects) {
			if(obj.getName().equals("Rocks")) {
				log("get's here");
				rockMap.put("rock", obj);
				break;
			}
		}
		rockMap.put("mineable", true);
	}
};

 

Are you removing the old objects out of the map?

Seems to me you are only adding new objects to it :)

 

Khaleesi

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