feat(path): Refpathing to Eldritch
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 97 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 118 KiB |
|
After Width: | Height: | Size: 910 KiB |
|
After Width: | Height: | Size: 919 KiB |
|
After Width: | Height: | Size: 920 KiB |
|
Before Width: | Height: | Size: 129 KiB |
@@ -235,13 +235,13 @@ class Bot:
|
||||
bot._char.select_by_template("A5_WP")
|
||||
wait(1.0)
|
||||
bot._ui_manager.use_wp(4, 1)
|
||||
self.success = bot._template_finder.search_and_wait("SHENK_FLAME", time_out=20)[0]
|
||||
self.success = bot._template_finder.search_and_wait("ELDRITCH_0", time_out=20)[0]
|
||||
if not self.success:
|
||||
return
|
||||
bot._char.pre_buff()
|
||||
# eldritch
|
||||
bot._pather.traverse_nodes_fixed("ELDRITCH", bot._char)
|
||||
bot._char.kill_eldritch(bot._pather.get_fixed_path("ELDRITCH")[1])
|
||||
bot._pather.traverse_nodes(Location.ELDRITCH_START, Location.ELDRITCH_SAVE_DIST, bot._char)
|
||||
bot._char.kill_eldritch()
|
||||
wait(0.5)
|
||||
bot._picked_up_items = bot._pickit.pick_up_items(bot._char)
|
||||
# shenk
|
||||
|
||||
@@ -57,15 +57,18 @@ class Hammerdin(IChar):
|
||||
keyboard.send(self._skill_hotkeys["redemption"])
|
||||
wait(1.5, 2.0)
|
||||
|
||||
def kill_pindle(self):
|
||||
def kill_pindle(self) -> bool:
|
||||
wait(0.1, 0.15)
|
||||
self._pather.traverse_nodes(Location.PINDLE_SAVE_DIST, Location.PINDLE_END, self)
|
||||
if not self._pather.traverse_nodes(Location.PINDLE_SAVE_DIST, Location.PINDLE_END, self):
|
||||
return False
|
||||
self._cast_hammers(1)
|
||||
# pindle sometimes knocks back, get back in
|
||||
self._pather.traverse_nodes(Location.PINDLE_SAVE_DIST, Location.PINDLE_END, self)
|
||||
if not self._pather.traverse_nodes(Location.PINDLE_SAVE_DIST, Location.PINDLE_END, self):
|
||||
return False
|
||||
self._cast_hammers(6)
|
||||
wait(0.1, 0.15)
|
||||
self._do_redemption()
|
||||
return True
|
||||
|
||||
def kill_shenk(self, shenk_pos_screen: Tuple[float, float]):
|
||||
pos_monitor = self._screen.convert_screen_to_monitor(shenk_pos_screen)
|
||||
@@ -79,12 +82,11 @@ class Hammerdin(IChar):
|
||||
wait(0.1, 0.15)
|
||||
self._do_redemption()
|
||||
|
||||
def kill_eldritch(self, eldritch_pos_screen: Tuple[float, float]):
|
||||
pos_monitor = self._screen.convert_screen_to_monitor(eldritch_pos_screen)
|
||||
keyboard.send(self._skill_hotkeys["teleport"])
|
||||
custom_mouse.move(pos_monitor[0], pos_monitor[1], duration=(random.random() * 0.05 + 0.15))
|
||||
mouse.click(button="right")
|
||||
def kill_eldritch(self) -> bool:
|
||||
if not self._pather.traverse_nodes(Location.ELDRITCH_SAVE_DIST, Location.ELDRITCH_END, self):
|
||||
return False
|
||||
wait(0.1, 0.15)
|
||||
self._cast_hammers(6)
|
||||
wait(0.1, 0.15)
|
||||
self._do_redemption()
|
||||
return True
|
||||
|
||||
@@ -93,7 +93,7 @@ class IChar:
|
||||
pass
|
||||
|
||||
@abstract
|
||||
def kill_pindle(self):
|
||||
def kill_pindle(self) -> bool:
|
||||
pass
|
||||
|
||||
@abstract
|
||||
@@ -101,5 +101,5 @@ class IChar:
|
||||
pass
|
||||
|
||||
@abstract
|
||||
def kill_eldritch(self, eldritch_pos_screen):
|
||||
def kill_eldritch(self) -> bool:
|
||||
pass
|
||||
|
||||
@@ -59,21 +59,24 @@ class Sorceress(IChar):
|
||||
mouse.click(button="right")
|
||||
wait(delay[0], delay[1])
|
||||
|
||||
def kill_pindle(self):
|
||||
def kill_pindle(self) -> bool:
|
||||
delay = [0.2, 0.3]
|
||||
pindle_pos_abs = self._pather.find_abs_node_pos(104, self._screen.grab())
|
||||
cast_pos_abs = [pindle_pos_abs[0] * 0.9, pindle_pos_abs[1] * 0.9]
|
||||
cast_pos_monitor = self._screen.convert_abs_to_monitor(cast_pos_abs)
|
||||
self._main_attack(cast_pos_monitor, delay)
|
||||
self._left_attack(cast_pos_monitor, delay)
|
||||
self._main_attack(cast_pos_monitor, delay)
|
||||
self._left_attack(cast_pos_monitor, delay)
|
||||
wait(0.1, 0.15)
|
||||
# Move to items
|
||||
self._pather.traverse_nodes(Location.PINDLE_SAVE_DIST, Location.PINDLE_END, self)
|
||||
wait(0.1, 0.15)
|
||||
blizzard_cast_pos = self._screen.convert_abs_to_monitor([0, 0])
|
||||
self._main_attack(blizzard_cast_pos, delay)
|
||||
if pindle_pos_abs is not None:
|
||||
cast_pos_abs = [pindle_pos_abs[0] * 0.9, pindle_pos_abs[1] * 0.9]
|
||||
cast_pos_monitor = self._screen.convert_abs_to_monitor(cast_pos_abs)
|
||||
self._main_attack(cast_pos_monitor, delay)
|
||||
self._left_attack(cast_pos_monitor, delay)
|
||||
self._main_attack(cast_pos_monitor, delay)
|
||||
self._left_attack(cast_pos_monitor, delay)
|
||||
wait(0.1, 0.15)
|
||||
# Move to items
|
||||
self._pather.traverse_nodes(Location.PINDLE_SAVE_DIST, Location.PINDLE_END, self)
|
||||
wait(0.1, 0.15)
|
||||
blizzard_cast_pos = self._screen.convert_abs_to_monitor([0, 0])
|
||||
self._main_attack(blizzard_cast_pos, delay)
|
||||
return True
|
||||
return False
|
||||
|
||||
def kill_shenk(self, shenk_pos_screen: Tuple[float, float]):
|
||||
delay = [0.2, 0.3]
|
||||
@@ -95,22 +98,22 @@ class Sorceress(IChar):
|
||||
custom_mouse.move(pos_monitor[0], pos_monitor[1], duration=(random.random() * 0.05 + 0.15))
|
||||
mouse.click(button="right")
|
||||
|
||||
def kill_eldritch(self, eldritch_pos_screen: Tuple[float, float]):
|
||||
def kill_eldritch(self) -> bool:
|
||||
delay = [0.2, 0.3]
|
||||
pos_abs = self._screen.convert_screen_to_abs(eldritch_pos_screen)
|
||||
cast_pos_abs = [pos_abs[0] * 0.9, pos_abs[1] * 0.9]
|
||||
cast_pos_monitor = self._screen.convert_abs_to_monitor(cast_pos_abs)
|
||||
pos_monitor = self._screen.convert_screen_to_monitor(eldritch_pos_screen)
|
||||
self._main_attack(cast_pos_monitor, delay, 90)
|
||||
self._left_attack(cast_pos_monitor, delay, 90)
|
||||
self._main_attack(cast_pos_monitor, delay, 90)
|
||||
self._main_attack(cast_pos_monitor, delay, 90)
|
||||
self._left_attack(cast_pos_monitor, delay, 90)
|
||||
wait(0.2, 0.3)
|
||||
# Move to items
|
||||
keyboard.send(self._skill_hotkeys["teleport"])
|
||||
custom_mouse.move(pos_monitor[0], pos_monitor[1], duration=(random.random() * 0.05 + 0.15))
|
||||
mouse.click(button="right")
|
||||
pos_abs = self._pather.find_abs_node_pos(123, self._screen.grab())
|
||||
if pos_abs is not None:
|
||||
cast_pos_abs = [pos_abs[0] * 0.9, pos_abs[1] * 0.9]
|
||||
cast_pos_monitor = self._screen.convert_abs_to_monitor(cast_pos_abs)
|
||||
self._main_attack(cast_pos_monitor, delay, 90)
|
||||
self._left_attack(cast_pos_monitor, delay, 90)
|
||||
self._main_attack(cast_pos_monitor, delay, 90)
|
||||
self._main_attack(cast_pos_monitor, delay, 90)
|
||||
self._left_attack(cast_pos_monitor, delay, 90)
|
||||
wait(0.2, 0.3)
|
||||
# Move to items
|
||||
self._pather.traverse_nodes(Location.ELDRITCH_SAVE_DIST, Location.ELDRITCH_END, self)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -24,9 +24,13 @@ class Location:
|
||||
MALAH = "malah"
|
||||
NIHLATHAK_PORTAL = "nihlathak_portal"
|
||||
# Pindle
|
||||
PINDLE_START = "PINDLE_START"
|
||||
PINDLE_SAVE_DIST = "PINDLE_SAVE_DIST"
|
||||
PINDLE_END = "PINDLE_END"
|
||||
PINDLE_START = "pindle_aster"
|
||||
PINDLE_SAVE_DIST = "pindle_save_dist"
|
||||
PINDLE_END = "pindle_end"
|
||||
# Eldritch
|
||||
ELDRITCH_START = "eldritch_start"
|
||||
ELDRITCH_SAVE_DIST = "eldritch_save_dist"
|
||||
ELDRITCH_END = "eldritch_end"
|
||||
|
||||
|
||||
class Pather:
|
||||
@@ -64,6 +68,11 @@ class Pather:
|
||||
102: {"PINDLE_3": (334, 132), "PINDLE_4": (142, 323)},
|
||||
103: {"PINDLE_3": (593, -113), "PINDLE_4": (401, 78)},
|
||||
104: {"PINDLE_4": (1076, -176), "PINDLE_3": (1264, -366), "PINDLE_5": (-280, 356), "PINDLE_6": (-700, 133)},
|
||||
# Eldritch
|
||||
120: {"ELDRITCH_0": (439, 236), "ELDRITCH_1": (-461, 314)},
|
||||
121: {"ELDRITCH_1": (-493, -155), "ELDRITCH_2": (616, 257), "ELDRITCH_3": (-137, 297)},
|
||||
122: {"ELDRITCH_2": (530, -218), "ELDRITCH_3": (-223, -178)},
|
||||
123: {"ELDRITCH_3": (-148, -498), "ELDRITCH_2": (604, -538), "ELDRITCH_4": (-163, -283)}
|
||||
}
|
||||
self._paths = {
|
||||
# A5 Town
|
||||
@@ -81,12 +90,13 @@ class Pather:
|
||||
# Pindle
|
||||
(Location.PINDLE_START, Location.PINDLE_SAVE_DIST): [100, 101, 102, 103],
|
||||
(Location.PINDLE_SAVE_DIST, Location.PINDLE_END): [104],
|
||||
# Eldritch
|
||||
(Location.ELDRITCH_START, Location.ELDRITCH_SAVE_DIST): [120, 121, 122],
|
||||
(Location.ELDRITCH_SAVE_DIST, Location.ELDRITCH_END): [123],
|
||||
}
|
||||
self._fixed_tele_path = {
|
||||
# 0: path to boss, 1: location of boss
|
||||
"PINDLE": ([(1382, 53), (1685, 105), (1429, 122)], (1533, 327)),
|
||||
"PINDLE_END": ([(600, 40)], None),
|
||||
"ELDRITCH": ([(978, 95), (845, 109)], (1012, 42)),
|
||||
"PINDLE_END": ([(600, 40)], None), # to move away from items
|
||||
"SHENK": ([(798, 869), (1112, 882), (1220, 860), (1330, 869), (1502, 836), (1247, 887), (1258, 901), (1463, 814), (1351, 778)], [1815, 772])
|
||||
}
|
||||
|
||||
@@ -94,24 +104,25 @@ class Pather:
|
||||
def get_fixed_path(self, key: str):
|
||||
return self._fixed_tele_path[key]
|
||||
|
||||
def _display_all_nodes_debug(self):
|
||||
def _display_all_nodes_debug(self, filter: str = None):
|
||||
while 1:
|
||||
img = self._screen.grab()
|
||||
for node_idx in self._nodes:
|
||||
for template_type in self._nodes[node_idx]:
|
||||
success, ref_pos_screen = self._template_finder.search(template_type, img)
|
||||
if success:
|
||||
# Get reference position of template in abs coordinates
|
||||
ref_pos_abs = self._screen.convert_screen_to_abs(ref_pos_screen)
|
||||
# Calc the abs node position with the relative coordinates (relative to ref)
|
||||
node_pos_rel = self._nodes[node_idx][template_type]
|
||||
node_pos_abs = self._convert_rel_to_abs(node_pos_rel, ref_pos_abs)
|
||||
node_pos_abs = self._adjust_abs_range_to_screen(node_pos_abs)
|
||||
x, y = self._screen.convert_abs_to_screen(node_pos_abs)
|
||||
cv2.circle(img, (x, y), 5, (255, 0, 0), 3)
|
||||
cv2.putText(img, str(node_idx), (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2, cv2.LINE_AA)
|
||||
x, y = self._screen.convert_abs_to_monitor(ref_pos_abs)
|
||||
cv2.circle(img, (x, y), 5, (0, 255, 0), 3)
|
||||
if filter is None or filter in template_type:
|
||||
success, ref_pos_screen = self._template_finder.search(template_type, img)
|
||||
if success:
|
||||
# Get reference position of template in abs coordinates
|
||||
ref_pos_abs = self._screen.convert_screen_to_abs(ref_pos_screen)
|
||||
# Calc the abs node position with the relative coordinates (relative to ref)
|
||||
node_pos_rel = self._nodes[node_idx][template_type]
|
||||
node_pos_abs = self._convert_rel_to_abs(node_pos_rel, ref_pos_abs)
|
||||
node_pos_abs = self._adjust_abs_range_to_screen(node_pos_abs)
|
||||
x, y = self._screen.convert_abs_to_screen(node_pos_abs)
|
||||
cv2.circle(img, (x, y), 5, (255, 0, 0), 3)
|
||||
cv2.putText(img, str(node_idx), (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2, cv2.LINE_AA)
|
||||
x, y = self._screen.convert_abs_to_monitor(ref_pos_abs)
|
||||
cv2.circle(img, (x, y), 5, (0, 255, 0), 3)
|
||||
img = cv2.resize(img, None, fx=0.5, fy=0.5)
|
||||
cv2.imshow("debug", img)
|
||||
cv2.waitKey(1)
|
||||
@@ -226,7 +237,7 @@ if __name__ == "__main__":
|
||||
t_finder = TemplateFinder(screen)
|
||||
pather = Pather(screen, t_finder)
|
||||
ui_manager = UiManager(screen, t_finder)
|
||||
char = Sorceress(config.sorceress, config.char, screen, t_finder, ui_manager)
|
||||
char = Sorceress(config.sorceress, config.char, screen, t_finder, ui_manager, pather)
|
||||
# pather.traverse_nodes_fixed("PINDLE", char)
|
||||
pather.traverse_nodes(Location.A5_TOWN_START, Location.MALAH, char, debug=True)
|
||||
# pather._display_all_nodes()
|
||||
# pather.traverse_nodes(Location.A5_TOWN_START, Location.MALAH, char, debug=True)
|
||||
pather._display_all_nodes_debug(filter="ELDRITCH")
|
||||
|
||||
@@ -44,8 +44,12 @@ class TemplateFinder:
|
||||
"PINDLE_4": [load_template("assets/templates/pindle/pindle_4.png", self._scale_factor), self._scale_factor],
|
||||
"PINDLE_5": [load_template("assets/templates/pindle/pindle_5.png", self._scale_factor), self._scale_factor],
|
||||
"PINDLE_6": [load_template("assets/templates/pindle/pindle_6.png", self._scale_factor), self._scale_factor],
|
||||
# Template Shenk area (currently only used to check if we are at shenk at wp, the walking is done statically)
|
||||
"SHENK_FLAME": [load_template("assets/templates/shenk_flame.png", self._scale_factor), self._scale_factor],
|
||||
# Teplates for nodes to Eldritch
|
||||
"ELDRITCH_0": [load_template("assets/templates/eldritch/eldritch_0.png", self._scale_factor), self._scale_factor],
|
||||
"ELDRITCH_1": [load_template("assets/templates/eldritch/eldritch_1.png", self._scale_factor), self._scale_factor],
|
||||
"ELDRITCH_2": [load_template("assets/templates/eldritch/eldritch_2.png", self._scale_factor), self._scale_factor],
|
||||
"ELDRITCH_3": [load_template("assets/templates/eldritch/eldritch_3.png", self._scale_factor), self._scale_factor],
|
||||
"ELDRITCH_4": [load_template("assets/templates/eldritch/eldritch_4.png", self._scale_factor), self._scale_factor],
|
||||
# Template Selectables
|
||||
"A5_STASH": [load_template("assets/templates/a5_stash.png", self._scale_factor), self._scale_factor],
|
||||
"A5_WP": [load_template("assets/templates/a5_wp.png", self._scale_factor), self._scale_factor],
|
||||
|
||||