Imthabawse Posted May 26, 2019 Share Posted May 26, 2019 So whipped up a quick smither for some AFK gains and realized the bot will interact with the anvil after making a couple Platebody's. Would appreciate any feedback on why this is happening. Spoiler private void smithPlateBodys() throws InterruptedException { RS2Object anvil = getObjects().closest("Anvil"); RS2Widget smithMenu = getWidgets().getWidgetContainingText("What would you like to make?"); RS2Widget plateBody = getWidgets().get(312,15,2); if(!smithArea.contains(myPosition()) && !getBank().isOpen()) { log("Walking to Anvil..."); getWalking().webWalk(smithArea); } if(!myPlayer().isAnimating() && smithArea.contains(myPosition()) && smithMenu == null && plateBody == null && !getDialogues().isPendingContinuation() && anvil != null && anvil.interact("Smith")) { log("Interacting with Anvil..."); new ConditionalSleep(5000) { @Override public boolean condition() { return getWidgets().getWidgetContainingText("What would you like to make?") != null; } }.sleep(); } if(smithMenu != null && plateBody != null && plateBody.interact("Smith All")) { log("Smithing Platebody's..."); new ConditionalSleep(10000) { @Override public boolean condition() { return !readyToSmith() || getInventory().getAmount("Iron platebody") == 5; } }.sleep(); } if(getDialogues().isPendingContinuation()) { log("Handling dialogue..."); sleep(random(500,700)); getDialogues().clickContinue(); } } Quote Link to comment Share on other sites More sharing options...
Neanel Posted May 26, 2019 Share Posted May 26, 2019 Use sleepUntil: & then just make a function like private boolean canMakePlatebodies(){ return getInventory().getAmount("Iron bar") >= 5; } //In your function Sleep.sleepUntil(() -> !canMakePlatebodies, 5000); 1 Quote Link to comment Share on other sites More sharing options...
Imthabawse Posted May 26, 2019 Author Share Posted May 26, 2019 (edited) 1 hour ago, Neanel said: Use sleepUntil: & then just make a function like private boolean canMakePlatebodies(){ return getInventory().getAmount("Iron bar") >= 5; } //In your function Sleep.sleepUntil(() -> !canMakePlatebodies, 5000); Actually have my onLoop setup like so: If (readyToSmith ()) { smithPlates (); }else { bankPlates (); readyToSmith is same as youre canMakePlatebodies Pretty sure my logics just jumbled up.. made it in 10 min or so, so didnt expect it to work flawlessly. Appreciate your feedback though! Edited May 26, 2019 by Imthabawse Quote Link to comment Share on other sites More sharing options...
Neanel Posted May 26, 2019 Share Posted May 26, 2019 Well that's exactly why he keeps interacting with the anvil again, the "readyToSmith()" function would still be true even if you are smithing because you'd have iron bars. With the "sleepUntil" he would be idle until you CAN'T smith anymore At some point you're everything in your first if-statement is true which causes it to interact with the anvil again. Quote Link to comment Share on other sites More sharing options...
HeyImJamie Posted May 26, 2019 Share Posted May 26, 2019 Go look at how conditional sleeps work in the API. That should fix your issue. Rather than sleeping though, I suggest creating an animation timer. The benefit of this over a conditional sleep would be that should your event break through a level up etc, it'll react quicker than it would with your conditional sleep setup. 2 Quote Link to comment Share on other sites More sharing options...
Tom Posted May 27, 2019 Share Posted May 27, 2019 8 hours ago, Malcolm said: I had this issue in my cannonballer script. I ended up making an interaction timer instead of using a conditional sleep. If you use a conditional sleep you're stopping the thread for that time which is something I personally would avoid. Just make a variable for when your last movement was and then do something like this. if (myPlayer().isAnimating()) { lastAnimation = System.currentTimeMillis(); } else if (System.currentTimeMillis() > (lastAnimation + 3000)) { if (furnace.interact("Smelt")) { ... The correct solution. Quote Link to comment Share on other sites More sharing options...
Juggles Posted May 27, 2019 Share Posted May 27, 2019 https://osbot.org/forum/topic/115705-simple-animation-timer/ 1 Quote Link to comment Share on other sites More sharing options...
Imthabawse Posted May 27, 2019 Author Share Posted May 27, 2019 Thanks for all the help everyone! I will look into animation timing when I get some time. Quote Link to comment Share on other sites More sharing options...
liverare Posted May 27, 2019 Share Posted May 27, 2019 Try avoid re-checking the same logic cases and instead structure your code to run the fewest number of checks as possible: private void smithPlateBodys() throws InterruptedException { if(smithArea.contains(myPosition())) { RS2Object anvil = getObjects().closest("Anvil"); RS2Widget smithMenu = getWidgets().getWidgetContainingText("What would you like to make?"); RS2Widget plateBody = getWidgets().get(312,15,2); if (getDialogues().isPendingContinuation()) { log("Handling dialogue..."); if (getDialogues().clickContinue()) { sleep(random(500,700)); } } else if (smithMenu != null && plateBody != null) { log("Smithing Platebody's..."); new ConditionalSleep(10000) { @Override public boolean condition() { return !readyToSmith() || getInventory().getAmount("Iron platebody") == 5; } }.sleep(); } else if (anvil != null && !myPlayer().isAnimating()) { log("Interacting with Anvil..."); if (anvil.interact("Smith")) { new ConditionalSleep(5000) { @Override public boolean condition() { return getWidgets().getWidgetContainingText("What would you like to make?") != null; } }.sleep(); } } } else { log("Walking to Anvil..."); if (getWalking().webWalk(smithArea)) { sleep(random(500,700)); } } } 1 Quote Link to comment Share on other sites More sharing options...
Imthabawse Posted May 27, 2019 Author Share Posted May 27, 2019 1 hour ago, liverare said: Try avoid re-checking the same logic cases and instead structure your code to run the fewest number of checks as possible: private void smithPlateBodys() throws InterruptedException { if(smithArea.contains(myPosition())) { RS2Object anvil = getObjects().closest("Anvil"); RS2Widget smithMenu = getWidgets().getWidgetContainingText("What would you like to make?"); RS2Widget plateBody = getWidgets().get(312,15,2); if (getDialogues().isPendingContinuation()) { log("Handling dialogue..."); if (getDialogues().clickContinue()) { sleep(random(500,700)); } } else if (smithMenu != null && plateBody != null) { log("Smithing Platebody's..."); new ConditionalSleep(10000) { @Override public boolean condition() { return !readyToSmith() || getInventory().getAmount("Iron platebody") == 5; } }.sleep(); } else if (anvil != null && !myPlayer().isAnimating()) { log("Interacting with Anvil..."); if (anvil.interact("Smith")) { new ConditionalSleep(5000) { @Override public boolean condition() { return getWidgets().getWidgetContainingText("What would you like to make?") != null; } }.sleep(); } } } else { log("Walking to Anvil..."); if (getWalking().webWalk(smithArea)) { sleep(random(500,700)); } } } Got this working. Thanks a lot. Will still be looking into animation timers as I've had this problem in scripts where your animation bounces from -1 to animating within seconds. Quote Link to comment Share on other sites More sharing options...
liverare Posted May 27, 2019 Share Posted May 27, 2019 3 hours ago, Imthabawse said: Got this working. Thanks a lot. Will still be looking into animation timers as I've had this problem in scripts where your animation bounces from -1 to animating within seconds. You don't need to watch for animations: // Some basic mathematics... long barsInInventory = inventory.getAmount("Bronze bar"); long barsPerPlatebody = 5; long platebodiesWeCanMake = (barsInInventory / barsPerPlatebody); // let's figure out how long we need to sleep long timeToMakeEachPlatebody = 1500; // 1.5 seconds (might be more or less don't know) long timeToMakePlatebodies = (platebodiesWeCanMake * timeToMakeEachPlatebody); long timeToMakePlatebodiesWithRandomOffset = (timeToMakePlatebodies + random(500, 1500)); // + 0.5 to 1.5 seconds if (anvil.interact("Smith")) { new ConditionalSleep(timeToMakePlatebodiesWithRandomOffset) { @Override public boolean condition() { // if any of the following happen, then we need to wake up! return getDialogues().isPendingContinuation() // level up message || inventory.getAmount("Bronze bar") == 0 // we're out of bronze bars || (inventory.getAmount("Bronze bar") / barsPerPlatebody) == 0; // we don't have enough bars to make another platebody } }.sleep(); } 1 Quote Link to comment Share on other sites More sharing options...