Jump to content

Creating Area with Array of position


Recommended Posts

Posted

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

 

 

Posted (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 by ExtraBotz
Posted
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();
            }
  • Like 1
Posted (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
O08BYkn.png

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 by Khaleesi
  • Like 2
Posted
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
O08BYkn.png

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 <3 

  • Like 2
Posted
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
O08BYkn.png

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.

Posted (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 by Khaleesi
  • Like 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...