elemt Posted September 21, 2015 Share Posted September 21, 2015 (edited) 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 September 21, 2015 by elemt Quote Link to comment Share on other sites More sharing options...
Lemons Posted September 21, 2015 Share Posted September 21, 2015 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. Quote Link to comment Share on other sites More sharing options...
elemt Posted September 22, 2015 Author Share Posted September 22, 2015 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; } } } Quote Link to comment Share on other sites More sharing options...
Bobrocket Posted September 22, 2015 Share Posted September 22, 2015 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. Quote Link to comment Share on other sites More sharing options...
elemt Posted September 22, 2015 Author Share Posted September 22, 2015 (edited) 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 Edited September 22, 2015 by elemt Quote Link to comment Share on other sites More sharing options...
FrostBug Posted September 22, 2015 Share Posted September 22, 2015 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. Quote Link to comment Share on other sites More sharing options...
Khaleesi Posted September 22, 2015 Share Posted September 22, 2015 (edited) 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 You'll have to update your rock list frequently to make sure you got the latest objects (I tried to interact with my non existing girlfriend once before, unfortunately nothing happend... :'( Should have null checked her before ... -_- ) Khaleesi Edited September 22, 2015 by Khaleesi 2 Quote Link to comment Share on other sites More sharing options...
Bobrocket Posted September 22, 2015 Share Posted September 22, 2015 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 You'll have to update your rock list frequently to make sure you got the latest objects (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 Quote Link to comment Share on other sites More sharing options...
Khaleesi Posted September 22, 2015 Share Posted September 22, 2015 (edited) Remember to perform instanceof Girl, because both Boy and Girl extend the abstract Person class Oh damn ... Thx for telling me! Don't want to get a shemale in my bed .... Wait a second... How do you know all this? Tried before? Edited September 22, 2015 by Khaleesi 1 Quote Link to comment Share on other sites More sharing options...
Bobrocket Posted September 22, 2015 Share Posted September 22, 2015 Oh damn ... Thx for telling me! Don't want to get a shemale in my bed .... Wait a second... How do you know all this? Tried before? A magician never reveals his tricks. 1 Quote Link to comment Share on other sites More sharing options...
elemt Posted September 22, 2015 Author Share Posted September 22, 2015 I do get a new object. After the timertask executes and the run() is invoked, I get a new rock instance and put it in the map Quote Link to comment Share on other sites More sharing options...
FrostBug Posted September 22, 2015 Share Posted September 22, 2015 I do get a new object. After the timertask executes and the run() is invoked, I get a new rock instance and put it in the map A new boolean value; not a new RS2Object representing the rock. You have to use the filter again Quote Link to comment Share on other sites More sharing options...
elemt Posted September 22, 2015 Author Share Posted September 22, 2015 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); } }; Quote Link to comment Share on other sites More sharing options...
Khaleesi Posted September 23, 2015 Share Posted September 23, 2015 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 Quote Link to comment Share on other sites More sharing options...
elemt Posted September 23, 2015 Author Share Posted September 23, 2015 Are you removing the old objects out of the map? Seems to me you are only adding new objects to it Khaleesi The put() method in a map replaces the old value for an existing key. Quote Link to comment Share on other sites More sharing options...