Teamwork Posted May 1, 2022 Share Posted May 1, 2022 Hello first post on the forum! I've started writing a firemaking/woodcutting script where I chop wood, then light the logs and pick up the ashes. Whenever I light a log I add my current position to an arraylist of positions called positionsOfFiresMade so that I can track where I should look for ashes instead of wandering everywhere or waiting indefinitely for other players fires to burn. Here's the part of the code where I'm in the firemaking state and I don't have any more logs to burn. if (inventory.isFull()) { switchToBanking(); } else { //transform the arraylist into an array final Position[] firePositionsAsArray = positionsOfFiresMade.toArray(new Position[positionsOfFiresMade.size()]); //look for ashes where we lit fires up GroundItem ashes = getGroundItems().closest(new Area(firePositionsAsArray), "Ashes"); if (ashes != null) { ashes.interact("Take"); new ConditionalSleep(3000) { @Override public boolean condition() { return (!ashes.exists()); } }.sleep(); } //not currently any ashes to pick up but check for any fires left else if (objects.closest(new Area(firePositionsAsArray), "Fire") != null) { new ConditionalSleep(5000) { @Override public boolean condition() { return (getGroundItems().closest(new Area(firePositionsAsArray),"Ashes") != null); } }.sleep(); } //if no fires close else { //bank the ashes if (inventory.contains("Ashes")) { switchToBanking(); } else { switchToWoodCutting(); } } } Sometimes there are ashes on the ground and the script doesn't seem to notice because he doesn't pick them up. When I change getGroundItems().closest(new Area(firePositionsAsArray), "Ashes") to getGroundItems().closest("Ashes") then it ends up picking the ashes except that the script wanders off since it doesn't have a restricted area to look for ashes. I'm guessing the problem comes from the way I'm using an array of position to create an area. But in the API documentation it says public Area(Position[] positions) Constructs a polygonal area using each position as a point in the polygon. so I'm not certain of what it is that I'm doing wrong. If you have any advice on how I can fix this or improve in general don't hesitate. Thanks Quote Link to comment Share on other sites More sharing options...
ExtraBotz Posted May 1, 2022 Share Posted May 1, 2022 (edited) Hi @Teamworkwelcome to the forum! It looks like your creating a polygonal area which may be causing some issues with the API finding items in that area. Looking at the area class in the docs you might be better suited using the first and last position in your list and calling the Area(Position southWest, Position northEast) constructor to create a rectangular area. This would work best if the fires were lit in a straight line. Another solution is to light the fire in a specific area and search that area constantly. Here is a good resource to help with visualizing creating areas: https://explv.github.io/ Edited May 1, 2022 by ExtraBotz Quote Link to comment Share on other sites More sharing options...
Gunman Posted May 1, 2022 Share Posted May 1, 2022 2 hours ago, Teamwork said: ashes.interact("Take"); new ConditionalSleep(3000) { @Override public boolean condition() { return (!ashes.exists()); } }.sleep(); Should rearrange it like below so you only sleep if the interact method returns true, if it failed then you will be sleeping for nothing. if (ashes.interact("Take")) { new ConditionalSleep(3000) { @Override public boolean condition() { return (!ashes.exists()); } }.sleep(); } 1 Quote Link to comment Share on other sites More sharing options...
Khaleesi Posted May 1, 2022 Share Posted May 1, 2022 (edited) 4 hours ago, Teamwork said: Hello first post on the forum! I've started writing a firemaking/woodcutting script where I chop wood, then light the logs and pick up the ashes. Whenever I light a log I add my current position to an arraylist of positions called positionsOfFiresMade so that I can track where I should look for ashes instead of wandering everywhere or waiting indefinitely for other players fires to burn. Here's the part of the code where I'm in the firemaking state and I don't have any more logs to burn. if (inventory.isFull()) { switchToBanking(); } else { //transform the arraylist into an array final Position[] firePositionsAsArray = positionsOfFiresMade.toArray(new Position[positionsOfFiresMade.size()]); //look for ashes where we lit fires up GroundItem ashes = getGroundItems().closest(new Area(firePositionsAsArray), "Ashes"); if (ashes != null) { ashes.interact("Take"); new ConditionalSleep(3000) { @Override public boolean condition() { return (!ashes.exists()); } }.sleep(); } //not currently any ashes to pick up but check for any fires left else if (objects.closest(new Area(firePositionsAsArray), "Fire") != null) { new ConditionalSleep(5000) { @Override public boolean condition() { return (getGroundItems().closest(new Area(firePositionsAsArray),"Ashes") != null); } }.sleep(); } //if no fires close else { //bank the ashes if (inventory.contains("Ashes")) { switchToBanking(); } else { switchToWoodCutting(); } } } Sometimes there are ashes on the ground and the script doesn't seem to notice because he doesn't pick them up. When I change getGroundItems().closest(new Area(firePositionsAsArray), "Ashes") to getGroundItems().closest("Ashes") then it ends up picking the ashes except that the script wanders off since it doesn't have a restricted area to look for ashes. I'm guessing the problem comes from the way I'm using an array of position to create an area. But in the API documentation it says public Area(Position[] positions) Constructs a polygonal area using each position as a point in the polygon. so I'm not certain of what it is that I'm doing wrong. If you have any advice on how I can fix this or improve in general don't hesitate. Thanks As far as I know if you create an area with a list of tiles, it tries to create a boundary with them. Like if you gives tile in a circle, it will draw imaginary lines in between them and every tile that falls in there counts as in the area. So you will get very strange behaviour on how you use it If you give 6 tiles in an odd shape, I believe it does something like this. Correct me if I'm wrong @Patrick Try to use this code to get an ash from your list private GroundItem getClosestAshesByTiles(List<Position> tiles) { return script.getGroundItems().closest(groundItem -> groundItem!= null && groundItem.getName().equals("Ashes") && tiles.contains(groundItem.getPosition())); } Edited May 1, 2022 by Khaleesi 2 Quote Link to comment Share on other sites More sharing options...
minewarriors Posted May 1, 2022 Share Posted May 1, 2022 7 hours ago, Khaleesi said: As far as I know if you create an area with a list of tiles, it tries to create a boundary with them. Like if you gives tile in a circle, it will draw imaginary lines in between them and every tile that falls in there counts as in the area. So you will get very strange behaviour on how you use it If you give 6 tiles in an odd shape, I believe it does something like this. Correct me if I'm wrong @Patrick Try to use this code to get an ash from your list private GroundItem getClosestAshesByTiles(List<Position> tiles) { return script.getGroundItems().closest(groundItem -> groundItem!= null && groundItem.getName().equals("Ashes") && tiles.contains(groundItem.getPosition())); } @Khaleesi to the rescue 2 Quote Link to comment Share on other sites More sharing options...
Teamwork Posted May 1, 2022 Author Share Posted May 1, 2022 12 hours ago, ExtraBotz said: Hi @Teamworkwelcome to the forum! It looks like your creating a polygonal area which may be causing some issues with the API finding items in that area. Looking at the area class in the docs you might be better suited using the first and last position in your list and calling the Area(Position southWest, Position northEast) constructor to create a rectangular area. This would work best if the fires were lit in a straight line. Another solution is to light the fire in a specific area and search that area constantly. Here is a good resource to help with visualizing creating areas: https://explv.github.io/ Yeah I thought about looping through the array and getting a minX, maxX, minY, maxY and creating 2 Positions to use the constructor you pointed out. It was better than letting it wander off for sure, but It was a sort of last resort solution. 10 hours ago, Gunman said: Should rearrange it like below so you only sleep if the interact method returns true, if it failed then you will be sleeping for nothing. if (ashes.interact("Take")) { new ConditionalSleep(3000) { @Override public boolean condition() { return (!ashes.exists()); } }.sleep(); } That's so much more efficient and clean thanks. I always forget that a lot of methods return true when they are able to successfully execute. 9 hours ago, Khaleesi said: As far as I know if you create an area with a list of tiles, it tries to create a boundary with them. Like if you gives tile in a circle, it will draw imaginary lines in between them and every tile that falls in there counts as in the area. So you will get very strange behaviour on how you use it If you give 6 tiles in an odd shape, I believe it does something like this. Correct me if I'm wrong @Patrick Try to use this code to get an ash from your list private GroundItem getClosestAshesByTiles(List<Position> tiles) { return script.getGroundItems().closest(groundItem -> groundItem!= null && groundItem.getName().equals("Ashes") && tiles.contains(groundItem.getPosition())); } Ahhh makes sense, so since I'm creating the fires in a row from east to west and then going south or north and doing the same thing again it probably ends up looking like a snake shape that doesn't have most of the positions I thought it did. I'll use the method you made, it looks really good. Thanks a lot I'm not that good of a programmer but I'm trying to understand what's happening in your code, correct me if I'm wrong. The method signature you're using is the one with Filter<E> and then you pass an anonymous function to filter through the results right? I'm looking at the Filter interface in the API right now and honestly I don't understand much hahaha. Quote Link to comment Share on other sites More sharing options...
Khaleesi Posted May 1, 2022 Share Posted May 1, 2022 (edited) 3 hours ago, Teamwork said: Yeah I thought about looping through the array and getting a minX, maxX, minY, maxY and creating 2 Positions to use the constructor you pointed out. It was better than letting it wander off for sure, but It was a sort of last resort solution. That's so much more efficient and clean thanks. I always forget that a lot of methods return true when they are able to successfully execute. Ahhh makes sense, so since I'm creating the fires in a row from east to west and then going south or north and doing the same thing again it probably ends up looking like a snake shape that doesn't have most of the positions I thought it did. I'll use the method you made, it looks really good. Thanks a lot I'm not that good of a programmer but I'm trying to understand what's happening in your code, correct me if I'm wrong. The method signature you're using is the one with Filter<E> and then you pass an anonymous function to filter through the results right? I'm looking at the Filter interface in the API right now and honestly I don't understand much hahaha. Yes basicly it's just a filter. You pass on what result you would filter in the results and then it will the closest one of all the results Edited May 1, 2022 by Khaleesi 1 Quote Link to comment Share on other sites More sharing options...