Jump to content

Creating Area with Array of position


Teamwork

Recommended Posts

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

 

 

Link to comment
Share on other sites

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

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

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

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

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.

Link to comment
Share on other sites

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