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

Commit 75d56bd

Browse files
authored
Merge pull request #130 from dubalols/feat/reference_rect
Add Rectangle sorting key function and improve RuneLiteBot loot function
2 parents f64b644 + 993f3aa commit 75d56bd

File tree

3 files changed

+37
-4
lines changed

3 files changed

+37
-4
lines changed

src/model/runelite_bot.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def is_player_doing_action(self, action: str):
116116
def pick_up_loot(self, items: Union[str, List[str]], supress_warning=True) -> bool:
117117
"""
118118
Attempts to pick up a single purple loot item off the ground. It is your responsibility to ensure you have
119-
enough inventory space to pick up the item.
119+
enough inventory space to pick up the item. The item closest to the game view center is picked up first.
120120
Args:
121121
item: The name(s) of the item(s) to pick up (E.g. -> "Coins", or "coins, bones", or ["Coins", "Dragon bones"]).
122122
Returns:
@@ -131,7 +131,10 @@ def pick_up_loot(self, items: Union[str, List[str]], supress_warning=True) -> bo
131131
items = self.capitalize_loot_list(items, to_list=True)
132132
# Locate Ground Items text
133133
if item_text := ocr.find_text(items, self.win.game_view, ocr.PLAIN_11, clr.PURPLE):
134-
self.mouse.move_to(item_text[len(item_text) // 2].get_center())
134+
for item in item_text:
135+
item.set_rectangle_reference(self.win.game_view)
136+
sorted_by_closest = sorted(item_text, key=Rectangle.distance_from_center)
137+
self.mouse.move_to(sorted_by_closest[0].get_center())
135138
for _ in range(5):
136139
if self.mouseover_text(contains=["Take"] + items, color=[clr.OFF_WHITE, clr.OFF_ORANGE]):
137140
break

src/utilities/geometry.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class Rectangle:
2222
"""
2323

2424
subtract_list: List[dict] = []
25+
reference_rect = None
2526

2627
def __init__(self, left: int, top: int, width: int, height: int):
2728
"""
@@ -40,6 +41,15 @@ def __init__(self, left: int, top: int, width: int, height: int):
4041
self.width = width
4142
self.height = height
4243

44+
def set_rectangle_reference(self, rect):
45+
"""
46+
Sets the rectangle reference of the object.
47+
Args:
48+
rect: A reference to the the rectangle that this object belongs in
49+
(E.g., Bot.win.game_view).
50+
"""
51+
self.reference_rect = rect
52+
4353
@classmethod
4454
def from_points(cls, start_point: Point, end_point: Point):
4555
"""
@@ -100,6 +110,20 @@ def get_center(self) -> Point:
100110
"""
101111
return Point(self.left + self.width // 2, self.top + self.height // 2)
102112

113+
# TODO: Consider changing to this to accept a Point to check against; `distance_from(point: Point)`
114+
def distance_from_center(self) -> Point:
115+
"""
116+
Gets the distance between the object and it's Rectangle parent center.
117+
Useful for sorting lists of Rectangles.
118+
Returns:
119+
The distance from the point to the center of the object.
120+
"""
121+
if self.reference_rect is None:
122+
raise ReferenceError("A Rectangle being sorted is missing a reference to the Rectangle it's contained in and therefore cannot be sorted.")
123+
center: Point = self.get_center()
124+
rect_center: Point = self.reference_rect.get_center()
125+
return math.dist([center.x, center.y], [rect_center.x, rect_center.y])
126+
103127
def get_top_left(self) -> Point:
104128
"""
105129
Gets the top left point of the rectangle.
@@ -181,12 +205,12 @@ def set_rectangle_reference(self, rect: Rectangle):
181205

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

192216
def distance_from_rect_center(self) -> float:
@@ -195,6 +219,8 @@ def distance_from_rect_center(self) -> float:
195219
Useful for sorting lists of RuneLiteObjects.
196220
Returns:
197221
The distance from the point to the center of the object.
222+
Note:
223+
Only use this if you're sorting a list of RuneLiteObjects that are contained in the same Rectangle.
198224
"""
199225
center: Point = self.center()
200226
rect_center: Point = self.rect.get_center()

src/utilities/runelite_cv.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
"""
22
A set of computer vision utilities for use with RuneLite-based bots.
3+
4+
TODO: Similarly to OCR, should these functions accept the Rect as an argument and do
5+
the screenshotting/color manipulation here? It would allow each RL Object to be created
6+
with its Rectangle reference property.
37
"""
48
from typing import List
59

0 commit comments

Comments
 (0)