omni4life Posted August 16, 2015 Share Posted August 16, 2015 (edited) Hey guys, I'm currently just throwing together a quick Willow Cutter for Barbarian Assault. At present it cuts fine, RETURNS from the bank fine but it won't WALK to the bank. This is my banking case: Variable from start of script (private Position[] bankPos = { new Position(2535, 3574, 0) }; ) case BANK: if (inventory.isFull()) { localWalker.walkPath(bankPos); status = "Banking"; Entity chest = objects.closest(true, bankChest); if (!bank.isOpen()) { if (chest != null) { if (chest.isVisible()) { if (!myPlayer().isMoving()) { chest.interact("Use"); sleep(random(1000, 1500)); } } } else { camera.toEntity(chest); } } else if (getInventory().contains( "Bronze axe, Iron axe, Steel axe, Black axe, Mithril axe, Adamant axe, Rune axe, Dragon axe")) { bank.depositAllExcept( "Bronze axe, Iron axe, Steel axe, Black axe, Mithril axe, Adamant axe, Rune axe, Dragon axe"); } else { bank.depositAll(); } } break; When I manually override and walk my character to the bank chest within the building, it begins to walk perfectly fine and interacts with the chest and banks properly and walks back to the willows without any issues, however, it just won't walk to the chest under its own power. I'm not too sure what I'm not seeing that's causing this issue. It enters the 'banking' state in the paint. Any and all advice is most welcome. -Omni. (Complete code in case it is required) import org.osbot.rs07.api.map.Position; import org.osbot.rs07.api.model.Entity; import org.osbot.rs07.api.model.GroundItem; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import java.awt.*; @ScriptManifest(name = "Willow Cutter", author = "Omni", version = 1.0, info = "A simple Willow Cutter for Barbarian Assault", logo = "") public class OmniCutter extends Script { public static String status; private Position[] barbWillows = { new Position(2518, 3576, 0) }; private Position[] bankPos = { new Position(2535, 3574, 0) }; private int bankChest = 19051; @Override public void onStart() { status = "OmniCutter is beginning."; } private enum State { CUT, BANK, SLEEP, WALK2TREE, NESTGRAB }; private State getState() { Entity tree = objects.closest("Willow"); if (inventory.isFull()) { return State.BANK; } else { if (myPlayer().isAnimating()) { return State.SLEEP; } else { if (tree != null && !myPlayer().isAnimating()) { return State.CUT; } else { if (inventory.isEmptyExcept("Hatchet")) { return State.WALK2TREE; } else { GroundItem nest = groundItems.closest("Birds Nest"); if (nest != null && nest.exists()) { return State.NESTGRAB; } else { return State.SLEEP; } } } } } } @Override public void onExit() { log("OmniCutter is exiting. Thank you for running."); } @Override public int onLoop() throws InterruptedException { switch (getState()) { case CUT: Entity tree = objects.closest("Willow"); if (!inventory.isFull() && !myPlayer().isAnimating() && !myPlayer().isMoving()) { camera.toEntity(tree); tree.interact("Chop Down"); status = "Clicking Willow"; sleep(random(2500, 3000)); } break; case BANK: if (inventory.isFull()) { localWalker.walkPath(bankPos); status = "Banking"; Entity chest = objects.closest(true, bankChest); if (!bank.isOpen()) { if (chest != null) { if (chest.isVisible()) { if (!myPlayer().isMoving()) { chest.interact("Use"); sleep(random(1000, 1500)); } } } else { camera.toEntity(chest); } } else if (getInventory().contains( "Bronze axe, Iron axe, Steel axe, Black axe, Mithril axe, Adamant axe, Rune axe, Dragon axe")) { bank.depositAllExcept( "Bronze axe, Iron axe, Steel axe, Black axe, Mithril axe, Adamant axe, Rune axe, Dragon axe"); } else { bank.depositAll(); } } break; case WALK2TREE: status = "Returning to Willows"; localWalker.walkPath(barbWillows); break; case NESTGRAB: GroundItem nest = groundItems.closest("Birds Nest"); if (nest != null && nest.exists()) { nest.interact("Take"); } case SLEEP: status = "Sleeping"; sleep(random(200, 300)); break; } return random(500, 800); } @Override public void onPaint(Graphics2D g) { g.drawString("Status: " + status, 4, 333); // This is where you will put your code for paint(s) } } Edited August 16, 2015 by omni4life Quote Link to comment Share on other sites More sharing options...
Twin Posted August 16, 2015 Share Posted August 16, 2015 You need two states, one to walk to the bank, and one to actually bank. To make it walk to the bank, do an area check and then check if the invenntory is full. To make it bank, check if it's in the bank area and if the inventory is full. 1 Quote Link to comment Share on other sites More sharing options...
Apaec Posted August 16, 2015 Share Posted August 16, 2015 get rid of all of the 'else's in your getState. if a statement is false, it will automatically check the next one down as this is how java code reads. I don't think at first glance that this will change how the script functions (its a little hard to see from the formatting - if you use eclipse, press ctrl+alt+f frequently), but it will make it much easier to read and debug. To debug it, I suggest putting log statements between every line of your banking code to see where the problem is. This will show you where the code gets to and doesn't get to.. Also, don't use localWalker.walkPath(position). I see why you used an array but instead of doing this, hop onto the sdn and use the divin pathrecording tool (i think thats what it's called), and record a full Position[] path of all the positions between the bank and the trees. Also on a side note: private Position[] barbWillows = { new Position(2518, 3576, 0) }; private Position[] bankPos = { new Position(2535, 3574, 0) }; ew. That's storing a single piece of data in an array. Seeing as the length of the array never changes, you're better off defining it as: private Position barbWillows = new Position(2518, 3576, 0); private Position bankPos = new Position(2535, 3574, 0); apa Quote Link to comment Share on other sites More sharing options...
omni4life Posted August 16, 2015 Author Share Posted August 16, 2015 get rid of all of the 'else's in your getState. if a statement is false, it will automatically check the next one down as this is how java code reads. I don't think at first glance that this will change how the script functions (its a little hard to see from the formatting - if you use eclipse, press ctrl+alt+f frequently), but it will make it much easier to read and debug. To debug it, I suggest putting log statements between every line of your banking code to see where the problem is. This will show you where the code gets to and doesn't get to.. Also, don't use localWalker.walkPath(position). I see why you used an array but instead of doing this, hop onto the sdn and use the divin pathrecording tool (i think thats what it's called), and record a full Position[] path of all the positions between the bank and the trees. Also on a side note: private Position[] barbWillows = { new Position(2518, 3576, 0) }; private Position[] bankPos = { new Position(2535, 3574, 0) }; ew. That's storing a single piece of data in an array. Seeing as the length of the array never changes, you're better off defining it as: private Position barbWillows = new Position(2518, 3576, 0); private Position bankPos = new Position(2535, 3574, 0); apa That makes for way cleaner code, thank you . I'm basically entirely new to Java and more or less coding in general so I'm learning as I run here. I think I've implemented what you're suggesting however I'm still having some issues with my walking. I now successfully walk to the bank, however, once I get there it doesn't change state from WALK2BANK to BANK and I'm not entirely sure why. I'm almost certain is has something to do with my bankArea.contains(myPlayer()) however I can't work out what exactly. This is my updated code. Any insight is more than welcome from anyone . Also, apologies for spamming this forum over the last few days. I'm quite eager to learn to script however my lack of background is showing though. import org.osbot.rs07.api.map.Area; import org.osbot.rs07.api.map.Position; import org.osbot.rs07.api.model.Entity; import org.osbot.rs07.api.model.GroundItem; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import java.awt.*; @ScriptManifest(name = "Willow Cutter", author = "Omni", version = 1.0, info = "A simple Willow Cutter for Barbarian Assault", logo = "") public class OmniCutter extends Script { public static String status; private Position[] barbWillows = new Position[] { new Position(2536, 3573, 0), new Position(2522, 3571, 0), new Position(2519, 3581, 0), }; private Position[] bankPos = new Position[] { new Position(2519, 3579, 0), new Position(2527, 3571, 0), new Position(2529, 3571, 0), new Position(2531, 3571, 0), new Position(2533, 3573, 0), new Position(2535, 3574, 0), }; Area bankArea = new Area( new Position[] { new Position(2536, 3573, 0), new Position(2536, 3574, 0), new Position(2535, 3574, 0), new Position(2535, 3573, 0), new Position(2535, 3572, 0), new Position(2536, 3572, 0), }); private int bankChest = 19051; @Override public void onStart() { status = "OmniCutter is beginning."; } private enum State { CUT, BANK, SLEEP, WALK2TREE, WALK2BANK, NESTGRAB }; private State getState() { Entity tree = objects.closest("Willow"); GroundItem nest = groundItems.closest("Birds Nest"); if (inventory.isFull()) { return State.WALK2BANK; } if (myPlayer().isAnimating()) { return State.SLEEP; } if (tree != null && !myPlayer().isAnimating()) { return State.CUT; } if (inventory.isEmptyExcept("Hatchet")) { return State.WALK2TREE; } if (nest != null && nest.exists()) { return State.NESTGRAB; } if (inventory.isFull() && bankArea.contains(myPlayer())) { return State.BANK; } return State.SLEEP; } @Override public void onExit() { log("OmniCutter is exiting. Thank you for running."); } @Override public int onLoop() throws InterruptedException { switch (getState()) { case CUT: Entity tree = objects.closest("Willow"); if (!inventory.isFull() && !myPlayer().isAnimating() && !myPlayer().isMoving()) { camera.toEntity(tree); tree.interact("Chop Down"); status = "Clicking Willow"; sleep(random(2500, 3000)); } break; case BANK: if (inventory.isFull() && bankArea.contains(myPlayer())) { status = "Banking"; Entity chest = objects.closest(true, bankChest); if (!bank.isOpen()) { if (chest != null) { if (chest.isVisible()) { if (!myPlayer().isMoving()) { chest.interact("Use"); sleep(random(1000, 1500)); } } } else { camera.toEntity(chest); } } else if (getInventory().contains( "Bronze axe, Iron axe, Steel axe, Black axe, Mithril axe, Adamant axe, Rune axe, Dragon axe")) { bank.depositAllExcept( "Bronze axe, Iron axe, Steel axe, Black axe, Mithril axe, Adamant axe, Rune axe, Dragon axe"); } else { bank.depositAll(); sleep(random(200, 300)); } } break; case WALK2TREE: status = "Returning to Willows"; localWalker.walkPath(barbWillows); break; case WALK2BANK: status = "Walking to bank"; localWalker.walkPath(bankPos); break; case NESTGRAB: GroundItem nest = groundItems.closest("Birds Nest"); if (nest != null && nest.exists()) { nest.interact("Take"); } break; case SLEEP: status = "Sleeping"; sleep(random(200, 300)); break; } return random(500, 800); } @Override public void onPaint(Graphics2D g) { g.drawString("Status: " + status, 4, 333); // This is where you will put your code for paint(s) } } Quote Link to comment Share on other sites More sharing options...
Flamezzz Posted August 16, 2015 Share Posted August 16, 2015 if (inventory.isFull()) { return State.WALK2BANK; } So if your inventory is full, you always return State.WALK2BANK. I think you want to move if (inventory.isFull() && bankArea.contains(myPlayer())) { return State.BANK; } this before the other if so that it is evaluated first. 1 Quote Link to comment Share on other sites More sharing options...
Apaec Posted August 16, 2015 Share Posted August 16, 2015 That makes for way cleaner code, thank you . I'm basically entirely new to Java and more or less coding in general so I'm learning as I run here. I think I've implemented what you're suggesting however I'm still having some issues with my walking. I now successfully walk to the bank, however, once I get there it doesn't change state from WALK2BANK to BANK and I'm not entirely sure why. I'm almost certain is has something to do with my bankArea.contains(myPlayer()) however I can't work out what exactly. This is my updated code. Any insight is more than welcome from anyone . Also, apologies for spamming this forum over the last few days. I'm quite eager to learn to script however my lack of background is showing though. import org.osbot.rs07.api.map.Area; import org.osbot.rs07.api.map.Position; import org.osbot.rs07.api.model.Entity; import org.osbot.rs07.api.model.GroundItem; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import java.awt.*; @ScriptManifest(name = "Willow Cutter", author = "Omni", version = 1.0, info = "A simple Willow Cutter for Barbarian Assault", logo = "") public class OmniCutter extends Script { public static String status; private Position[] barbWillows = new Position[] { new Position(2536, 3573, 0), new Position(2522, 3571, 0), new Position(2519, 3581, 0), }; private Position[] bankPos = new Position[] { new Position(2519, 3579, 0), new Position(2527, 3571, 0), new Position(2529, 3571, 0), new Position(2531, 3571, 0), new Position(2533, 3573, 0), new Position(2535, 3574, 0), }; Area bankArea = new Area( new Position[] { new Position(2536, 3573, 0), new Position(2536, 3574, 0), new Position(2535, 3574, 0), new Position(2535, 3573, 0), new Position(2535, 3572, 0), new Position(2536, 3572, 0), }); private int bankChest = 19051; @Override public void onStart() { status = "OmniCutter is beginning."; } private enum State { CUT, BANK, SLEEP, WALK2TREE, WALK2BANK, NESTGRAB }; private State getState() { Entity tree = objects.closest("Willow"); GroundItem nest = groundItems.closest("Birds Nest"); if (inventory.isFull()) { return State.WALK2BANK; } if (myPlayer().isAnimating()) { return State.SLEEP; } if (tree != null && !myPlayer().isAnimating()) { return State.CUT; } if (inventory.isEmptyExcept("Hatchet")) { return State.WALK2TREE; } if (nest != null && nest.exists()) { return State.NESTGRAB; } if (inventory.isFull() && bankArea.contains(myPlayer())) { return State.BANK; } return State.SLEEP; } @Override public void onExit() { log("OmniCutter is exiting. Thank you for running."); } @Override public int onLoop() throws InterruptedException { switch (getState()) { case CUT: Entity tree = objects.closest("Willow"); if (!inventory.isFull() && !myPlayer().isAnimating() && !myPlayer().isMoving()) { camera.toEntity(tree); tree.interact("Chop Down"); status = "Clicking Willow"; sleep(random(2500, 3000)); } break; case BANK: if (inventory.isFull() && bankArea.contains(myPlayer())) { status = "Banking"; Entity chest = objects.closest(true, bankChest); if (!bank.isOpen()) { if (chest != null) { if (chest.isVisible()) { if (!myPlayer().isMoving()) { chest.interact("Use"); sleep(random(1000, 1500)); } } } else { camera.toEntity(chest); } } else if (getInventory().contains( "Bronze axe, Iron axe, Steel axe, Black axe, Mithril axe, Adamant axe, Rune axe, Dragon axe")) { bank.depositAllExcept( "Bronze axe, Iron axe, Steel axe, Black axe, Mithril axe, Adamant axe, Rune axe, Dragon axe"); } else { bank.depositAll(); sleep(random(200, 300)); } } break; case WALK2TREE: status = "Returning to Willows"; localWalker.walkPath(barbWillows); break; case WALK2BANK: status = "Walking to bank"; localWalker.walkPath(bankPos); break; case NESTGRAB: GroundItem nest = groundItems.closest("Birds Nest"); if (nest != null && nest.exists()) { nest.interact("Take"); } break; case SLEEP: status = "Sleeping"; sleep(random(200, 300)); break; } return random(500, 800); } @Override public void onPaint(Graphics2D g) { g.drawString("Status: " + status, 4, 333); // This is where you will put your code for paint(s) } } Hey! dont worry about spamming the forums, that's what they're for The reason it's not switching to the bank state is because the script reads like an instruction manual - you start at the top and go down. So in the state machine which you have there, it will first check to see if your inventory is full (and if it is, it will return the walktobank state). if not, it will check the next one down the list and so on. The reason that it's not switching to the bank state is because it's always returning walkToBank as your inventory is still full. Put the check for the bank state ABOVE the walkToBank state. That will fix your problem - I hope you understand why this will fix it, if you do not, let me know and i will have another go at explaining it haha. Or just try and think it through logically ;) apa 1 Quote Link to comment Share on other sites More sharing options...
omni4life Posted August 16, 2015 Author Share Posted August 16, 2015 (edited) Hey! dont worry about spamming the forums, that's what they're for The reason it's not switching to the bank state is because the script reads like an instruction manual - you start at the top and go down. So in the state machine which you have there, it will first check to see if your inventory is full (and if it is, it will return the walktobank state). if not, it will check the next one down the list and so on. The reason that it's not switching to the bank state is because it's always returning walkToBank as your inventory is still full. Put the check for the bank state ABOVE the walkToBank state. That will fix your problem - I hope you understand why this will fix it, if you do not, let me know and i will have another go at explaining it haha. Or just try and think it through logically apa That fixed it perfectly , Thank you to everyone! It was so simple when I actually think about it. If you don't mind, I just have two more questions for now if anyone has time. I'm looking to create a simple safeguard the says "if no xp is gained in 10 minutes, terminate script, logout". I'm not too sure how to implement it. I know how to track XP gains as I've been using it in a paint I created thanks to Pugs tutorial, but I'm not totally sure how to actually write it. Would this be a simple enough job? I have my character set to dismiss randoms events. When it did this in my mining script, it actually caused to script to stop working. It didn't crash or anything, it was still running it just simply stood there as opposed to resuming mining. Is there any code I have to add in to say "pause script on random"? Thanks again to everyone here, I really appreciate how patient and helpful the community is. Edited August 16, 2015 by omni4life Quote Link to comment Share on other sites More sharing options...
Flamezzz Posted August 16, 2015 Share Posted August 16, 2015 (edited) 1. I would recommend counting the amount of times you loop and not use actual minutes, since this wouldn't work when taking breaks.Something like:int loopCount = 0in onLoop:loopCount++if(loopCount % 1000 == 0) // check if xp > last xp >>> Note: this failsafe wouldn't work when a flaw causes your script to not loop anymore (localwalker )2. When a RandomSolver is active your script is paused and once it's finished it will be resumed. So during this time onLoop will not be called. Edited August 16, 2015 by Flamezzz 1 Quote Link to comment Share on other sites More sharing options...
omni4life Posted August 16, 2015 Author Share Posted August 16, 2015 1. I would recommend counting the amount of times you loop and not use actual minutes, since this wouldn't work when taking breaks. Something like: int loopCount = 0 in onLoop: loopCount++ if(loopCount % 1000 == 0) // check if xp > last xp >>> Note: this failsafe wouldn't work when a flaw causes your script to not loop anymore (localwalker ) 2. When a RandomSolver is active your script is paused and once it's finished it will be resumed. So during this time onLoop will not be called. I'll toy around with that in the morning and see if I can get it working properly. I really appreciate you and everyone else taking the time to help me . I think the script is actually almost ready to be left alone for more than 20 minutes. Quote Link to comment Share on other sites More sharing options...
Joseph Posted August 16, 2015 Share Posted August 16, 2015 Apa was talking about divine utilities as the script that records paths. I'm going to update it soon Op for the failsafe I suggest making a fail safe timer. On the onloop you can throw in a simple method that just reset the timer to 0 whenever it animating and not fighting. Within that method you can add the if statement. If it passes the time frame end script. This doesn't not track your experience gain. But your players activity. Remember give the timer a decent amount of time. Cuz I know you have to walk to bank and back. Enjoy I'll toy around with that in the morning and see if I can get it working properly. I really appreciate you and everyone else taking the time to help me . I think the script is actually almost ready to be left alone for more than 20 minutes. 2 Quote Link to comment Share on other sites More sharing options...
omni4life Posted August 16, 2015 Author Share Posted August 16, 2015 Apa was talking about divine utilities as the script that records paths. I'm going to update it soon I actually used it once he suggested it, I'm definitely a fan of it. It makes life a lot easier and no doubt saved me a lot of time and fiddling. If I may make a suggestion (as someone with no experience so this might be a nightmare to do), when you have the auto collect path option selected you could be able to right click one of the recorded tiles in the GUI and delete it from the log and the output as I misclicked a few times and didn't want to have to return to the start of my path to re-record a more accurate version. I just manually edited it out of the Array after I got the code so no biggie, but that might make things a tiny bit easier. 1 Quote Link to comment Share on other sites More sharing options...
Joseph Posted August 16, 2015 Share Posted August 16, 2015 (edited) I actually used it once he suggested it, I'm definitely a fan of it. It makes life a lot easier and no doubt saved me a lot of time and fiddling. If I may make a suggestion (as someone with no experience so this might be a nightmare to do), when you have the auto collect path option selected you could be able to right click one of the recorded tiles in the GUI and delete it from the log and the output as I misclicked a few times and didn't want to have to return to the start of my path to re-record a more accurate version. I just manually edited it out of the Array after I got the code so no biggie, but that might make things a tiny bit easier. I could tell by the area you made. It gave you my format ;)Auto path collection give you a random distance. Displays it on the paint. With that being said it randomize when it collects a path. Also removing a tile all you do is right click the tile on the main screen. Edited August 16, 2015 by jos3dpay 1 Quote Link to comment Share on other sites More sharing options...
Bobrocket Posted August 16, 2015 Share Posted August 16, 2015 Hey dude, not trying to be like super Nazi or anything, but if you release your scripts on the SDN can you not prefix them with "Omni"? Saves people confusion Also, try moving to a node system rather than using states. It allows for cleaner code and can make less code required too 1 Quote Link to comment Share on other sites More sharing options...
omni4life Posted August 17, 2015 Author Share Posted August 17, 2015 (edited) Hey dude, not trying to be like super Nazi or anything, but if you release your scripts on the SDN can you not prefix them with "Omni"? Saves people confusion Also, try moving to a node system rather than using states. It allows for cleaner code and can make less code required too Yeah haha, I spotted your scripts last night and saw the issue. Don't worry, I won't be encroaching on your turf . I used to release under Omni on rscheata/iBot but I haven't had anything to do with this for years. I'll definitely not put Omni in any names or similar Also, regarding nodes, I haven't used Java for years. I had a look at it and for the time being, I think it's beyond my abilities. I'm trying to work towards being able to use it, but in the interim I'm just creating scripts that I actually have a use for to learn. Edited August 17, 2015 by omni4life 1 Quote Link to comment Share on other sites More sharing options...
Bobrocket Posted August 17, 2015 Share Posted August 17, 2015 Yeah haha, I spotted your scripts last night and saw the issue. Don't worry, I won't be encroaching on your turf . I used to release under Omni on rscheata/iBot but I haven't had anything to do with this for years. I'll definitely not put Omni in any names or similar Also, regarding nodes, I haven't used Java for years. I had a look at it and for the time being, I think it's beyond my abilities. I'm trying to work towards being able to use it, but in the interim I'm just creating scripts that I actually have a use for to learn. Thanks for understanding Also, states are perfectly fine if you enjoy looking at 1000+ lines of code purely in onLoop. Now, for smaller scripts, this is no issue (2 of my scripts still use states, as do most of my private scripts), but of course when your scripts get larger management is a lot easier with a node system. Doing it earlier simply gets you used to using it which really does help, believe me. Imagine all of these classes: All clustered into one class, it gets pretty hectic (not saying it would all be there anyway, just using it as an example). Nodes also enforce an OOP programming style, which is infinitely more useful (think objects instead of global variables). 1 Quote Link to comment Share on other sites More sharing options...