Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

Commit

Permalink
Merge pull request #130 from dubalols/feat/reference_rect
Browse files Browse the repository at this point in the history
Add Rectangle sorting key function and improve RuneLiteBot loot function
  • Loading branch information
kelltom authored Feb 8, 2023
2 parents f64b644 + 993f3aa commit 75d56bd
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
7 changes: 5 additions & 2 deletions src/model/runelite_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def is_player_doing_action(self, action: str):
def pick_up_loot(self, items: Union[str, List[str]], supress_warning=True) -> bool:
"""
Attempts to pick up a single purple loot item off the ground. It is your responsibility to ensure you have
enough inventory space to pick up the item.
enough inventory space to pick up the item. The item closest to the game view center is picked up first.
Args:
item: The name(s) of the item(s) to pick up (E.g. -> "Coins", or "coins, bones", or ["Coins", "Dragon bones"]).
Returns:
Expand All @@ -131,7 +131,10 @@ def pick_up_loot(self, items: Union[str, List[str]], supress_warning=True) -> bo
items = self.capitalize_loot_list(items, to_list=True)
# Locate Ground Items text
if item_text := ocr.find_text(items, self.win.game_view, ocr.PLAIN_11, clr.PURPLE):
self.mouse.move_to(item_text[len(item_text) // 2].get_center())
for item in item_text:
item.set_rectangle_reference(self.win.game_view)
sorted_by_closest = sorted(item_text, key=Rectangle.distance_from_center)
self.mouse.move_to(sorted_by_closest[0].get_center())
for _ in range(5):
if self.mouseover_text(contains=["Take"] + items, color=[clr.OFF_WHITE, clr.OFF_ORANGE]):
break
Expand Down
30 changes: 28 additions & 2 deletions src/utilities/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Rectangle:
"""

subtract_list: List[dict] = []
reference_rect = None

def __init__(self, left: int, top: int, width: int, height: int):
"""
Expand All @@ -40,6 +41,15 @@ def __init__(self, left: int, top: int, width: int, height: int):
self.width = width
self.height = height

def set_rectangle_reference(self, rect):
"""
Sets the rectangle reference of the object.
Args:
rect: A reference to the the rectangle that this object belongs in
(E.g., Bot.win.game_view).
"""
self.reference_rect = rect

@classmethod
def from_points(cls, start_point: Point, end_point: Point):
"""
Expand Down Expand Up @@ -100,6 +110,20 @@ def get_center(self) -> Point:
"""
return Point(self.left + self.width // 2, self.top + self.height // 2)

# TODO: Consider changing to this to accept a Point to check against; `distance_from(point: Point)`
def distance_from_center(self) -> Point:
"""
Gets the distance between the object and it's Rectangle parent center.
Useful for sorting lists of Rectangles.
Returns:
The distance from the point to the center of the object.
"""
if self.reference_rect is None:
raise ReferenceError("A Rectangle being sorted is missing a reference to the Rectangle it's contained in and therefore cannot be sorted.")
center: Point = self.get_center()
rect_center: Point = self.reference_rect.get_center()
return math.dist([center.x, center.y], [rect_center.x, rect_center.y])

def get_top_left(self) -> Point:
"""
Gets the top left point of the rectangle.
Expand Down Expand Up @@ -181,12 +205,12 @@ def set_rectangle_reference(self, rect: Rectangle):

def center(self) -> Point: # sourcery skip: raise-specific-error
"""
Gets the center of the object relative to the client.
Gets the center of the object relative to the containing Rectangle.
Returns:
A Point.
"""
if self.rect is None:
raise Exception("Rectangle reference not set for object.")
raise ReferenceError("The RuneLiteObject is missing a reference to the Rectangle it's contained in and therefore the center cannot be determined.")
return Point(self._center[0] + self.rect.left, self._center[1] + self.rect.top)

def distance_from_rect_center(self) -> float:
Expand All @@ -195,6 +219,8 @@ def distance_from_rect_center(self) -> float:
Useful for sorting lists of RuneLiteObjects.
Returns:
The distance from the point to the center of the object.
Note:
Only use this if you're sorting a list of RuneLiteObjects that are contained in the same Rectangle.
"""
center: Point = self.center()
rect_center: Point = self.rect.get_center()
Expand Down
4 changes: 4 additions & 0 deletions src/utilities/runelite_cv.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
"""
A set of computer vision utilities for use with RuneLite-based bots.
TODO: Similarly to OCR, should these functions accept the Rect as an argument and do
the screenshotting/color manipulation here? It would allow each RL Object to be created
with its Rectangle reference property.
"""
from typing import List

Expand Down

0 comments on commit 75d56bd

Please sign in to comment.