Jump to content

Issue with localWaler.walkPath


omni4life

Recommended Posts

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

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

Link to comment
Share on other sites

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)

	}

}
Link to comment
Share on other sites

 

That makes for way cleaner code, thank you smile.png. 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 smile.png. 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

  • Like 1
Link to comment
Share on other sites

Hey!

 

dont worry about spamming the forums, that's what they're for smile.png

 

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

 

apa

That fixed it perfectly smile.png,  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.

 

  1. 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?
  2. 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 by omni4life
Link to comment
Share on other sites

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 angry.png )

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

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 angry.png )

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. 

Link to comment
Share on other sites

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.

  • Like 2
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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

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

Also, try moving to a node system rather than using states. It allows for cleaner code and can make less code required too smile.png

Yeah haha, I spotted your scripts last night and saw the issue. Don't worry, I won't be encroaching on your turf smile.png. 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 smile.png

 

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

Yeah haha, I spotted your scripts last night and saw the issue. Don't worry, I won't be encroaching on your turf smile.png. 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 smile.png

 

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:

cc82a93632193feaa369702e137e5464.png

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

  • Like 1
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...