Neffarion 486 Posted February 10, 2021 In my experience, the DreamBot Web as good as it is on DB3 now, it still could be better in regard to interaction with objects and being teleported around to other places (like dungeons & caves and ship travelling for example). So a few months ago I started writing a "world walker", which is basically a simple layer on top of the DreamBot Web. I thought about making it open source, so that other scripters could use it or improve on it if they wish. All this simply does is bridge places which you couldn't possibly walk by using the default Web walker only. The code can be found here: https://github.com/0xNeffarion/DreamBot-WorldWalker So how do I use it? Pretty simple. Assuming you imported that code into your project, all you need to do is to add the places you want the pathfinder to be able to bridge on the start of your script and then call the walk function. You can check a few example nodes I already added in the pathfinder by going here (So there's no need to add the ones in there already) Adding nodes for a simple interaction example: @Override public void onStart(){ SimpleNode<GameObject> sn1 = new SimpleNode<>("Dwarven Mine to Falador", new Tile(3058, 9777, 0), "Staircase", "Climb-up", GameObject.class); SimpleNode<GameObject> sn2 = new SimpleNode<>("Falador to Dwarven Mine", new Tile(3061, 3377, 0), "Staircase", "Climb-down", GameObject.class); sn1.connect(sn2); sn2.connect(sn1); WorldWalking.getWorldPathFinder().addNodes(sn1, sn2); } Ship travelling example: @Override public void onStart(){ ShipTravelNode shipTravel1 = new ShipTravelNode("Port Sarim to Karamja", new Tile(3029, 3217, 0), "Seaman Lorris", "Talk-to", new String[]{"Yes please."}, new InventoryRequirement(COINS, 30)); ShipTravelNode shipTravel2 = new ShipTravelNode("Karamja to Port Sarim", new Tile(2954, 3146, 0), "Customs officer", "Talk-to", new String[]{"Can I journey on this ship?", "Ok."}, new InventoryRequirement(COINS, 30)); shipTravel1.connect(shipTravel2); shipTravel2.connect(shipTravel1); WorldWalking.getWorldPathFinder().addNodes(shipTravel1, shipTravel2); } If you don't have the requirements needed, the pathfinder will not be able to find a path and the walk method will return false (or will try to find some other way to get to the destination tile if possible) You can also use: WorldWalking.getWorldPathFinder().canReach() to check if you can get to the tile you want to go Walking usage: @Override public int onLoop(){ if(WorldWalking.shouldWalk()) { WorldWalking.walk(tileToWalkTo); } return 1000; } Note: that this is not to be used on simple local obstacles like doors, gates or even stairs which make you only move in the Z axis and keep you in the same region. For this purpose you need to add obstacles the normal way by adding them to the DreamBot's DijPathFinder (for different Z values) or AStarPathFinder for other things
Pandemic 2818 Posted February 10, 2021 Looks nice, and should do nicely until we get around to improving our web walker
Hashtag 8952 Posted February 11, 2021 I appreciate the contribution. However, considering this bridging you're talking about is already do-able with the existing webwalker, I find this a bit redundant.
Neffarion 486 Author Posted February 11, 2021 34 minutes ago, Hashtag said: I appreciate the contribution. However, considering this bridging you're talking about is already do-able with the existing webwalker, I find this a bit redundant. Not redundant at all. Firstly, adding web nodes like entrance web nodes for ourselves is more of a feat if it works at all. You have more control over the nodes here. Besides nothing related to traversing entrance web nodes is documented in the Javadocs (it's a mess) I'd welcome you to try and use the current walker to get from Karamja to the Dwarven Mine for example. Yeah... you can't at the moment The first example I gave for instance (Dwarven Mine to Falador) is mapped on the web and yet it doesn't work if you try it with the default web walker Then there's the absence of knowing what is required to go through the web nodes themselves (like skills or items for example, which can shorten the distance to the destination) Lastly, there's currently no ship travel support at all and there's nothing stopping you from creating your type of nodes to bridge whatever you want and traverse however you want
Hashtag 8952 Posted February 11, 2021 Challenge accepted. The following will walk from Karamja to Dwarven Mine only if you can afford the ship. Spoiler public class TestScript extends AbstractScript { @Override public void onStart() { Tile karamjaDock = new Tile(2952, 3147); Tile portSarimDock = new Tile(3028, 3222); Tile portSarimShip = new Tile(3032, 3217, 1); Tile falador = new Tile(3061, 3377); Tile dwarvenMine = new Tile(3058, 9777); // From Karamja to Port Sarim AbstractWebNode karamjaNode = Walking.getWebPathFinder().getNearest(karamjaDock, 15); AbstractWebNode portSarimNode = Walking.getWebPathFinder().getNearest(portSarimDock, 15); Walking.getWebPathFinder().addWebNode(new CustomWebNode(karamjaDock, "Customs officer", "Pay-Fare") .from(karamjaNode) .to(portSarimNode) .condition(() -> Inventory.count("Coins") >= 30) ); // Port Sarim ship gangplank BasicWebNode portSarimShipNode = new BasicWebNode(3034, 3216, 1); Walking.getWebPathFinder().addWebNode(portSarimShipNode); Walking.getWebPathFinder().addWebNode(new CustomWebNode(portSarimShip, "Gangplank", "Cross") .from(portSarimShipNode).to(portSarimNode)); // From Falador to Dwarven Mine AbstractWebNode existingFaladorNode = Walking.getWebPathFinder().getNearest(falador, 15); AbstractWebNode existingDwarvenMineNode = Walking.getWebPathFinder().getNearest(dwarvenMine, 15); Walking.getWebPathFinder().addWebNode(new CustomWebNode(falador, "Staircase", "Climb-down") .from(existingFaladorNode) .to(existingDwarvenMineNode) ); } @Override public int onLoop() { Walking.walk(3058, 9777); // Dwarven mine return 600; } @Override public void onExit() { Walking.getWebPathFinder().clearCustomNodes(); } class CustomWebNode extends EntranceWebNode { private Condition condition; public CustomWebNode(Tile tile, String entityName, String action) { super(tile.getX(), tile.getY(), tile.getZ()); setEntityName(entityName); setAction(action); } @Override public boolean execute(AbstractWebNode nextNode) { if (getTile().distance() > 10) { Walking.walk(getTile()); return false; } Entity entity = GameObjects.closest(getEntityName()); if (entity == null) { entity = NPCs.closest(getEntityName()); } if (entity != null) { if (Map.canReach(entity)) { if (entity.interact(getAction())) { MethodProvider.sleepUntil(() -> getTile().distance() > 20 || Client.getLocalPlayer().getZ() != getTile().getZ(), 10000); } } else { Walking.walk(entity); } } return false; } public CustomWebNode from(AbstractWebNode node) { node.addConnections(this); return this; } public CustomWebNode to(AbstractWebNode node) { this.addConnections(node); return this; } public CustomWebNode condition(Condition condition) { this.condition = condition; return this; } @Override public boolean hasRequirements() { return (condition == null || condition.verify()) && super.hasRequirements(); } @Override public boolean isValid() { return true; } } }
Neffarion 486 Author Posted February 11, 2021 33 minutes ago, Hashtag said: Challenge accepted. The following will walk from Karamja to Dwarven Mine only if you can afford the ship. Fair enough, I did try something like that in the past and yet it didn't work properly. Really wish this was better documented
Hashtag 8952 Posted February 11, 2021 5 minutes ago, Neffarion said: Fair enough, I did try something like that in the past and yet it didn't work properly. Really wish this was better documented I totally agree, a proper documentation for the webwalker would be much appreciated. It took me quite some time to understand how it works, and boy was it tedious at first when nothing worked. Hard work paid off and I learned the webwalker can actually handle any kind of traversal method you design for it.
Neffarion 486 Author Posted February 11, 2021 4 hours ago, Hashtag said: I totally agree, a proper documentation for the webwalker would be much appreciated. It took me quite some time to understand how it works, and boy was it tedious at first when nothing worked. Hard work paid off and I learned the webwalker can actually handle any kind of traversal method you design for it. Now I feel like I wasted a bunch of time lmao At least it was fun doing it
Aeglen 373 Posted February 12, 2021 10 hours ago, Hashtag said: Challenge accepted. The following will walk from Karamja to Dwarven Mine only if you can afford the ship. Reveal hidden contents public class TestScript extends AbstractScript { @Override public void onStart() { Tile karamjaDock = new Tile(2952, 3147); Tile portSarimDock = new Tile(3028, 3222); Tile portSarimShip = new Tile(3032, 3217, 1); Tile falador = new Tile(3061, 3377); Tile dwarvenMine = new Tile(3058, 9777); // From Karamja to Port Sarim AbstractWebNode karamjaNode = Walking.getWebPathFinder().getNearest(karamjaDock, 15); AbstractWebNode portSarimNode = Walking.getWebPathFinder().getNearest(portSarimDock, 15); Walking.getWebPathFinder().addWebNode(new CustomWebNode(karamjaDock, "Customs officer", "Pay-Fare") .from(karamjaNode) .to(portSarimNode) .condition(() -> Inventory.count("Coins") >= 30) ); // Port Sarim ship gangplank BasicWebNode portSarimShipNode = new BasicWebNode(3034, 3216, 1); Walking.getWebPathFinder().addWebNode(portSarimShipNode); Walking.getWebPathFinder().addWebNode(new CustomWebNode(portSarimShip, "Gangplank", "Cross") .from(portSarimShipNode).to(portSarimNode)); // From Falador to Dwarven Mine AbstractWebNode existingFaladorNode = Walking.getWebPathFinder().getNearest(falador, 15); AbstractWebNode existingDwarvenMineNode = Walking.getWebPathFinder().getNearest(dwarvenMine, 15); Walking.getWebPathFinder().addWebNode(new CustomWebNode(falador, "Staircase", "Climb-down") .from(existingFaladorNode) .to(existingDwarvenMineNode) ); } @Override public int onLoop() { Walking.walk(3058, 9777); // Dwarven mine return 600; } @Override public void onExit() { Walking.getWebPathFinder().clearCustomNodes(); } class CustomWebNode extends EntranceWebNode { private Condition condition; public CustomWebNode(Tile tile, String entityName, String action) { super(tile.getX(), tile.getY(), tile.getZ()); setEntityName(entityName); setAction(action); } @Override public boolean execute(AbstractWebNode nextNode) { if (getTile().distance() > 10) { Walking.walk(getTile()); return false; } Entity entity = GameObjects.closest(getEntityName()); if (entity == null) { entity = NPCs.closest(getEntityName()); } if (entity != null) { if (Map.canReach(entity)) { if (entity.interact(getAction())) { MethodProvider.sleepUntil(() -> getTile().distance() > 20 || Client.getLocalPlayer().getZ() != getTile().getZ(), 10000); } } else { Walking.walk(entity); } } return false; } public CustomWebNode from(AbstractWebNode node) { node.addConnections(this); return this; } public CustomWebNode to(AbstractWebNode node) { this.addConnections(node); return this; } public CustomWebNode condition(Condition condition) { this.condition = condition; return this; } @Override public boolean hasRequirements() { return (condition == null || condition.verify()) && super.hasRequirements(); } @Override public boolean isValid() { return true; } } } This example is really good, it teaches me some things I was handling without the WebWalker can actually be done with it. Nice.
Recommended Posts
Archived
This topic is now archived and is closed to further replies.