runelite-api/src/main/java/net/runelite/api/coords/WorldArea.java
/**
	 * Determines if the area can travel in one of the 8 directions
	 * by using the standard collision detection algorithm.
	 * Note that this method does not consider other actors as
	 * a collision, but most non-boss NPCs do check for collision
	 * with some actors.
	 *
	 * @param client The client to test in
	 * @param dx The x direction to test against
	 * @param dy The y direction to test against
	 * @param extraCondition Additional check for if movement is allowed through specific
	 * tiles, which may be used if movement should be disabled through other actors
	 * @return Returns true if it's possible to travel in specified direction
	 */
Determines if the area can travel in one of the 8 directions
by using the standard collision detection algorithm.
Note that this method does not consider other actors as
a collision, but most non-boss NPCs do check for collision
with some actors.


Determines if the area can travel in one of the 8 directions by using the standard collision detection algorithm . Note that this method does not consider other actors as a collision but most non - boss NPCs do check for collision with some actors .
public boolean canTravelInDirection(Client client, int dx, int dy,
										Predicate<? super WorldPoint> extraCondition)
	{
		dx = Integer.signum(dx);
		dy = Integer.signum(dy);
		if (dx == 0 && dy == 0)
		{
			return true;
		}
		LocalPoint lp = LocalPoint.fromWorld(client, x, y);
		int startX = lp.getRegionX() + dx;
		int startY = lp.getRegionY() + dy;
		int checkX = startX + (dx > 0 ? width - 1 : 0);
		int checkY = startY + (dy > 0 ? height - 1 : 0);
		int endX = startX + width - 1;
		int endY = startY + height - 1;
		int xFlags = CollisionDataFlag.BLOCK_MOVEMENT_FULL;
		int yFlags = CollisionDataFlag.BLOCK_MOVEMENT_FULL;
		int xyFlags = CollisionDataFlag.BLOCK_MOVEMENT_FULL;
		int xWallFlagsSouth = CollisionDataFlag.BLOCK_MOVEMENT_FULL;
		int xWallFlagsNorth = CollisionDataFlag.BLOCK_MOVEMENT_FULL;
		int yWallFlagsWest = CollisionDataFlag.BLOCK_MOVEMENT_FULL;
		int yWallFlagsEast = CollisionDataFlag.BLOCK_MOVEMENT_FULL;
		if (dx < 0)
		{
			xFlags |= CollisionDataFlag.BLOCK_MOVEMENT_EAST;
			xWallFlagsSouth |= CollisionDataFlag.BLOCK_MOVEMENT_SOUTH |
				CollisionDataFlag.BLOCK_MOVEMENT_SOUTH_EAST;
			xWallFlagsNorth |= CollisionDataFlag.BLOCK_MOVEMENT_NORTH |
				CollisionDataFlag.BLOCK_MOVEMENT_NORTH_EAST;
		}
		if (dx > 0)
		{
			xFlags |= CollisionDataFlag.BLOCK_MOVEMENT_WEST;
			xWallFlagsSouth |= CollisionDataFlag.BLOCK_MOVEMENT_SOUTH |
				CollisionDataFlag.BLOCK_MOVEMENT_SOUTH_WEST;
			xWallFlagsNorth |= CollisionDataFlag.BLOCK_MOVEMENT_NORTH |
				CollisionDataFlag.BLOCK_MOVEMENT_NORTH_WEST;
		}
		if (dy < 0)
		{
			yFlags |= CollisionDataFlag.BLOCK_MOVEMENT_NORTH;
			yWallFlagsWest |= CollisionDataFlag.BLOCK_MOVEMENT_WEST |
				CollisionDataFlag.BLOCK_MOVEMENT_NORTH_WEST;
			yWallFlagsEast |= CollisionDataFlag.BLOCK_MOVEMENT_EAST |
				CollisionDataFlag.BLOCK_MOVEMENT_NORTH_EAST;
		}
		if (dy > 0)
		{
			yFlags |= CollisionDataFlag.BLOCK_MOVEMENT_SOUTH;
			yWallFlagsWest |= CollisionDataFlag.BLOCK_MOVEMENT_WEST |
				CollisionDataFlag.BLOCK_MOVEMENT_SOUTH_WEST;
			yWallFlagsEast |= CollisionDataFlag.BLOCK_MOVEMENT_EAST |
				CollisionDataFlag.BLOCK_MOVEMENT_SOUTH_EAST;
		}
		if (dx < 0 && dy < 0)
		{
			xyFlags |= CollisionDataFlag.BLOCK_MOVEMENT_NORTH_EAST;
		}
		if (dx < 0 && dy > 0)
		{
			xyFlags |= CollisionDataFlag.BLOCK_MOVEMENT_SOUTH_EAST;
		}
		if (dx > 0 && dy < 0)
		{
			xyFlags |= CollisionDataFlag.BLOCK_MOVEMENT_NORTH_WEST;
		}
		if (dx > 0 && dy > 0)
		{
			xyFlags |= CollisionDataFlag.BLOCK_MOVEMENT_SOUTH_WEST;
		}
		CollisionData[] collisionData = client.getCollisionMaps();
		int[][] collisionDataFlags = collisionData[plane].getFlags();
		if (dx != 0)
		{
			for (int y = startY; y <= endY; y++)
			{
				if ((collisionDataFlags[checkX][y] & xFlags) != 0 ||
					!extraCondition.test(WorldPoint.fromRegion(client, checkX, y, plane)))
				{
					return false;
				}
			}
			for (int y = startY + 1; y <= endY; y++)
			{
				if ((collisionDataFlags[checkX][y] & xWallFlagsSouth) != 0)
				{
					return false;
				}
			}
			for (int y = endY - 1; y >= startY; y--)
			{
				if ((collisionDataFlags[checkX][y] & xWallFlagsNorth) != 0)
				{
					return false;
				}
			}
		}
		if (dy != 0)
		{
			for (int x = startX; x <= endX; x++)
			{
				if ((collisionDataFlags[x][checkY] & yFlags) != 0 ||
					!extraCondition.test(WorldPoint.fromRegion(client, x, checkY, client.getPlane())))
				{
					return false;
				}
			}
			for (int x = startX + 1; x <= endX; x++)
			{
				if ((collisionDataFlags[x][checkY] & yWallFlagsWest) != 0)
				{
					return false;
				}
			}
			for (int x = endX - 1; x >= startX; x--)
			{
				if ((collisionDataFlags[x][checkY] & yWallFlagsEast) != 0)
				{
					return false;
				}
			}
		}
		if (dx != 0 && dy != 0)
		{
			if ((collisionDataFlags[checkX][checkY] & xyFlags) != 0 ||
				!extraCondition.test(WorldPoint.fromRegion(client, checkX, checkY, client.getPlane())))
			{
				return false;
			}
			if (width == 1)
			{
				if ((collisionDataFlags[checkX][checkY - dy] & xFlags) != 0 &&
					extraCondition.test(WorldPoint.fromRegion(client, checkX, startY, client.getPlane())))
				{
					return false;
				}
			}
			if (height == 1)
			{
				if ((collisionDataFlags[checkX - dx][checkY] & yFlags) != 0 &&
					extraCondition.test(WorldPoint.fromRegion(client, startX, checkY, client.getPlane())))
				{
					return false;
				}
			}
		}
		return true;
	}
public boolean canTravelInDirection ( Client client , int dx , int dy , Predicate < ? super WorldPoint > extraCondition ) { dx = Integer . signum ( dx ) ; dy = Integer . signum ( dy ) ; if ( dx == 0 && dy == 0 ) { return true ; } LocalPoint lp = LocalPoint . fromWorld ( client , x , y ) ; int startX = lp . getRegionX ( ) + dx ; int startY = lp . getRegionY ( ) + dy ; int checkX = startX + ( dx > 0 ? width - 1 : 0 ) ; int checkY = startY + ( dy > 0 ? height - 1 : 0 ) ; int endX = startX + width - 1 ; int endY = startY + height - 1 ; int xFlags = CollisionDataFlag . BLOCK_MOVEMENT_FULL ; int yFlags = CollisionDataFlag . BLOCK_MOVEMENT_FULL ; int xyFlags = CollisionDataFlag . BLOCK_MOVEMENT_FULL ; int xWallFlagsSouth = CollisionDataFlag . BLOCK_MOVEMENT_FULL ; int xWallFlagsNorth = CollisionDataFlag . BLOCK_MOVEMENT_FULL ; int yWallFlagsWest = CollisionDataFlag . BLOCK_MOVEMENT_FULL ; int yWallFlagsEast = CollisionDataFlag . BLOCK_MOVEMENT_FULL ; if ( dx < 0 ) { xFlags |= CollisionDataFlag . BLOCK_MOVEMENT_EAST ; xWallFlagsSouth |= CollisionDataFlag . BLOCK_MOVEMENT_SOUTH | CollisionDataFlag . BLOCK_MOVEMENT_SOUTH_EAST ; xWallFlagsNorth |= CollisionDataFlag . BLOCK_MOVEMENT_NORTH | CollisionDataFlag . BLOCK_MOVEMENT_NORTH_EAST ; } if ( dx > 0 ) { xFlags |= CollisionDataFlag . BLOCK_MOVEMENT_WEST ; xWallFlagsSouth |= CollisionDataFlag . BLOCK_MOVEMENT_SOUTH | CollisionDataFlag . BLOCK_MOVEMENT_SOUTH_WEST ; xWallFlagsNorth |= CollisionDataFlag . BLOCK_MOVEMENT_NORTH | CollisionDataFlag . BLOCK_MOVEMENT_NORTH_WEST ; } if ( dy < 0 ) { yFlags |= CollisionDataFlag . BLOCK_MOVEMENT_NORTH ; yWallFlagsWest |= CollisionDataFlag . BLOCK_MOVEMENT_WEST | CollisionDataFlag . BLOCK_MOVEMENT_NORTH_WEST ; yWallFlagsEast |= CollisionDataFlag . BLOCK_MOVEMENT_EAST | CollisionDataFlag . BLOCK_MOVEMENT_NORTH_EAST ; } if ( dy > 0 ) { yFlags |= CollisionDataFlag . BLOCK_MOVEMENT_SOUTH ; yWallFlagsWest |= CollisionDataFlag . BLOCK_MOVEMENT_WEST | CollisionDataFlag . BLOCK_MOVEMENT_SOUTH_WEST ; yWallFlagsEast |= CollisionDataFlag . BLOCK_MOVEMENT_EAST | CollisionDataFlag . BLOCK_MOVEMENT_SOUTH_EAST ; } if ( dx < 0 && dy < 0 ) { xyFlags |= CollisionDataFlag . BLOCK_MOVEMENT_NORTH_EAST ; } if ( dx < 0 && dy > 0 ) { xyFlags |= CollisionDataFlag . BLOCK_MOVEMENT_SOUTH_EAST ; } if ( dx > 0 && dy < 0 ) { xyFlags |= CollisionDataFlag . BLOCK_MOVEMENT_NORTH_WEST ; } if ( dx > 0 && dy > 0 ) { xyFlags |= CollisionDataFlag . BLOCK_MOVEMENT_SOUTH_WEST ; } CollisionData [ ] collisionData = client . getCollisionMaps ( ) ; int [ ] [ ] collisionDataFlags = collisionData [ plane ] . getFlags ( ) ; if ( dx != 0 ) { for ( int y = startY ; y <= endY ; y ++ ) { if ( ( collisionDataFlags [ checkX ] [ y ] & xFlags ) != 0 || ! extraCondition . test ( WorldPoint . fromRegion ( client , checkX , y , plane ) ) ) { return false ; } } for ( int y = startY + 1 ; y <= endY ; y ++ ) { if ( ( collisionDataFlags [ checkX ] [ y ] & xWallFlagsSouth ) != 0 ) { return false ; } } for ( int y = endY - 1 ; y >= startY ; y -- ) { if ( ( collisionDataFlags [ checkX ] [ y ] & xWallFlagsNorth ) != 0 ) { return false ; } } } if ( dy != 0 ) { for ( int x = startX ; x <= endX ; x ++ ) { if ( ( collisionDataFlags [ x ] [ checkY ] & yFlags ) != 0 || ! extraCondition . test ( WorldPoint . fromRegion ( client , x , checkY , client . getPlane ( ) ) ) ) { return false ; } } for ( int x = startX + 1 ; x <= endX ; x ++ ) { if ( ( collisionDataFlags [ x ] [ checkY ] & yWallFlagsWest ) != 0 ) { return false ; } } for ( int x = endX - 1 ; x >= startX ; x -- ) { if ( ( collisionDataFlags [ x ] [ checkY ] & yWallFlagsEast ) != 0 ) { return false ; } } } if ( dx != 0 && dy != 0 ) { if ( ( collisionDataFlags [ checkX ] [ checkY ] & xyFlags ) != 0 || ! extraCondition . test ( WorldPoint . fromRegion ( client , checkX , checkY , client . getPlane ( ) ) ) ) { return false ; } if ( width == 1 ) { if ( ( collisionDataFlags [ checkX ] [ checkY - dy ] & xFlags ) != 0 && extraCondition . test ( WorldPoint . fromRegion ( client , checkX , startY , client . getPlane ( ) ) ) ) { return false ; } } if ( height == 1 ) { if ( ( collisionDataFlags [ checkX - dx ] [ checkY ] & yFlags ) != 0 && extraCondition . test ( WorldPoint . fromRegion ( client , startX , checkY , client . getPlane ( ) ) ) ) { return false ; } } } return true ; }
Determines if the area can travel in one of the 8 directions
 by using the standard collision detection algorithm.
Determines if the area can travel in one of the 8 directions by using the standard collision detection algorithm .
// Check that the area doesn't bypass a wall // Collision while attempting to travel along the x axis // Check that the new area tiles don't contain a wall // The new area tiles contains a wall // The new area tiles contains a wall // Check that the area tiles don't bypass a wall // Collision while attempting to travel along the y axis // Check that the new area tiles don't contain a wall // The new area tiles contains a wall // The new area tiles contains a wall // Collision while attempting to travel diagonally // When the areas edge size is 1 and it attempts to travel // diagonally, a collision check is done for respective // x and y axis as well.