TheJacob Posted January 22, 2023 Share Posted January 22, 2023 (edited) Can someone explain how to use the API area filter to filter undesirable positions from my next walk. I've figured out how to achieve this by converting the area to a list of positions & applying stream filter. That said, if there's a way native to the OSBot API, I'm definitely keen on using it. For example: Character player = myPlayer(); Area nowalk = player.getArea(1); // 3x3 area on player Area canwalk = player.getArea(2); // 5x5 area on player // How do I use the API Area Filter to exclude the list of "nowalk" positions from "canwalk". The desired output is an area of 16 tiles (outer edges of the 5x5). Edited January 22, 2023 by TheJacob Quote Link to comment Share on other sites More sharing options...
Chris Posted January 22, 2023 Share Posted January 22, 2023 22 minutes ago, TheJacob said: Can someone explain how to use the API area filter to filter undesirable positions from my next walk. I've figured out how to achieve this by converting the area to a list of positions & applying stream filter. That said, if there's a way native to the OSBot API, I'm definitely keen on using it. For example: Character player = myPlayer(); Area nowalk = player.getArea(1); // 3x3 area on player area canwalk = player.getArea(2); // 5x5 area on player // How do I use the API Area Filter to exclude the list of "nowalk" positions from "canwalk". The desired output is an area of 16 tiles (outer edges of the 5x5). Try this as a solution. As of now I don't think there is API for this but I may be wrong. You could always make a wrapper class that extends the Area API to create your own methods. Area nonWalk = ....; Area canWalk = ....; Area walkable = new Area((Position[]) canWalk.getPositions().stream().filter(nonWalk::contains).toArray()); 1 Quote Link to comment Share on other sites More sharing options...
TheJacob Posted January 22, 2023 Author Share Posted January 22, 2023 (edited) 28 minutes ago, Chris said: Try this as a solution. As of now I don't think there is API for this but I may be wrong. You could always make a wrapper class that extends the Area API to create your own methods. Area nonWalk = ....; Area canWalk = ....; Area walkable = new Area((Position[]) canWalk.getPositions().stream().filter(nonWalk::contains).toArray()); I came up with something similar, although both solutions still feel a bit weird. I'm quite new to Java and OSBot, am I reading the docs right when they state "Creates an instance of this filter, which filters out Entity objects based on whether their Position falls inside the Area." -- does this mean for the API area filter, it must convert these positions to an Entity before I can filter them? To me, it seems this native functionality is only applicable to filtering out objects from an area, not pathing? According to the docs, entities can only be: Character, GroundDecoration, GroundItem, InteractableObject, NPC, Player, WallDecoration, WallObject? Character p1 = myPlayer(); Area x = p1.getArea(1); Area y = p1.getArea(2); List<Position> walkable = y.getPositions().stream().filter( pos -> !x.contains(pos) ).collect(Collectors.toList()); Edited January 22, 2023 by TheJacob Quote Link to comment Share on other sites More sharing options...
Chris Posted January 22, 2023 Share Posted January 22, 2023 (edited) 1 hour ago, TheJacob said: "Creates an instance of this filter, which filters out Entity objects based on whether their Position falls inside the Area." -- does this mean for the API area filter, it must convert these positions to an Entity before I can filter them? The documentation for AreaFilter states that it will return a new Filter instance containing the Entities filtered by their position. It will check the entity positions to check whether they fall within the provided Area passed in as the parameter. Here is an example of its usage in the NPC API: closest method docs: https://osbot.org/api/org/osbot/rs07/api/EntityAPI.html#closest-org.osbot.rs07.api.filter.Filter...- getNpcs().closest(new PositionFilter<>(myPosition())); // Return the NPC that matches this filter // Get the closest NPC that is on my positon. getNpcs().closest(new AreaFilter<>(new Area(1,2,3,4))); // Get the closest NPC where their position is in this Area ..and so on Edited January 22, 2023 by Chris 1 Quote Link to comment Share on other sites More sharing options...
Chris Posted January 22, 2023 Share Posted January 22, 2023 (edited) 1 hour ago, TheJacob said: I came up with something similar, although both solutions still feel a bit weird. Character p1 = myPlayer(); Area x = p1.getArea(1); Area y = p1.getArea(2); List<Position> walkable = y.getPositions().stream().filter( pos -> !x.contains(pos) ).collect(Collectors.toList()); These can be equal by changing the final chain method call in my example. canWalk.getPositions().stream().filter(nonWalk::contains).collect(Collectors.toList()) //List<Position> The Area class accepts the following constructor: Area(Position[] positions) canWalk.getPositions().stream().filter(nonWalk::contains).toArray() The following returns an Object[] array and would not be accepted by the Position[] constructor parameter unless we cast onto the object. I am not sure if my example works as I have only typed it up and did not run a test script to verify. canWalk.getPositions().stream().filter(nonWalk::contains) //Note .filter(nonWalk::contains) is an example of a method reference https://www.tutorialspoint.com/differences-between-lambda-expression-and-method-reference-in-java https://www.baeldung.com/java-method-references Edited January 22, 2023 by Chris 1 Quote Link to comment Share on other sites More sharing options...