diff --git a/assets/templates/shenk/nodes/shenk_0.png b/assets/templates/shenk/nodes/shenk_0.png new file mode 100644 index 0000000..0fb566a Binary files /dev/null and b/assets/templates/shenk/nodes/shenk_0.png differ diff --git a/assets/templates/shenk/nodes/shenk_1.png b/assets/templates/shenk/nodes/shenk_1.png new file mode 100644 index 0000000..ed48bea Binary files /dev/null and b/assets/templates/shenk/nodes/shenk_1.png differ diff --git a/assets/templates/shenk/nodes/shenk_2.png b/assets/templates/shenk/nodes/shenk_2.png new file mode 100644 index 0000000..a08ffd8 Binary files /dev/null and b/assets/templates/shenk/nodes/shenk_2.png differ diff --git a/assets/templates/shenk/nodes/shenk_3.png b/assets/templates/shenk/nodes/shenk_3.png new file mode 100644 index 0000000..a94e1d9 Binary files /dev/null and b/assets/templates/shenk/nodes/shenk_3.png differ diff --git a/assets/templates/shenk/nodes/shenk_4.png b/assets/templates/shenk/nodes/shenk_4.png new file mode 100644 index 0000000..0048f7c Binary files /dev/null and b/assets/templates/shenk/nodes/shenk_4.png differ diff --git a/assets/templates/shenk/nodes/shenk_5.png b/assets/templates/shenk/nodes/shenk_5.png new file mode 100644 index 0000000..97df0d4 Binary files /dev/null and b/assets/templates/shenk/nodes/shenk_5.png differ diff --git a/assets/templates/shenk/nodes/shenk_6.png b/assets/templates/shenk/nodes/shenk_6.png new file mode 100644 index 0000000..9335348 Binary files /dev/null and b/assets/templates/shenk/nodes/shenk_6.png differ diff --git a/assets/templates/shenk/nodes/shenk_7.png b/assets/templates/shenk/nodes/shenk_7.png new file mode 100644 index 0000000..f251a43 Binary files /dev/null and b/assets/templates/shenk/nodes/shenk_7.png differ diff --git a/assets/templates/shenk/nodes/shenk_8.png b/assets/templates/shenk/nodes/shenk_8.png new file mode 100644 index 0000000..2290894 Binary files /dev/null and b/assets/templates/shenk/nodes/shenk_8.png differ diff --git a/assets/templates/shenk/nodes/shenk_9.png b/assets/templates/shenk/nodes/shenk_9.png new file mode 100644 index 0000000..047707e Binary files /dev/null and b/assets/templates/shenk/nodes/shenk_9.png differ diff --git a/assets/templates/shenk/shenk_0.png b/assets/templates/shenk/shenk_0.png new file mode 100644 index 0000000..e18af10 Binary files /dev/null and b/assets/templates/shenk/shenk_0.png differ diff --git a/assets/templates/shenk/shenk_1.png b/assets/templates/shenk/shenk_1.png new file mode 100644 index 0000000..7b8dee9 Binary files /dev/null and b/assets/templates/shenk/shenk_1.png differ diff --git a/assets/templates/shenk/shenk_10.png b/assets/templates/shenk/shenk_10.png new file mode 100644 index 0000000..88267a3 Binary files /dev/null and b/assets/templates/shenk/shenk_10.png differ diff --git a/assets/templates/shenk/shenk_11.png b/assets/templates/shenk/shenk_11.png new file mode 100644 index 0000000..1b125bd Binary files /dev/null and b/assets/templates/shenk/shenk_11.png differ diff --git a/assets/templates/shenk/shenk_12.png b/assets/templates/shenk/shenk_12.png new file mode 100644 index 0000000..0f1d1e6 Binary files /dev/null and b/assets/templates/shenk/shenk_12.png differ diff --git a/assets/templates/shenk/shenk_13.png b/assets/templates/shenk/shenk_13.png new file mode 100644 index 0000000..a731d7b Binary files /dev/null and b/assets/templates/shenk/shenk_13.png differ diff --git a/assets/templates/shenk/shenk_14.png b/assets/templates/shenk/shenk_14.png new file mode 100644 index 0000000..4847529 Binary files /dev/null and b/assets/templates/shenk/shenk_14.png differ diff --git a/assets/templates/shenk/shenk_2.png b/assets/templates/shenk/shenk_2.png new file mode 100644 index 0000000..6092632 Binary files /dev/null and b/assets/templates/shenk/shenk_2.png differ diff --git a/assets/templates/shenk/shenk_3.png b/assets/templates/shenk/shenk_3.png new file mode 100644 index 0000000..611f171 Binary files /dev/null and b/assets/templates/shenk/shenk_3.png differ diff --git a/assets/templates/shenk/shenk_4.png b/assets/templates/shenk/shenk_4.png new file mode 100644 index 0000000..def08bf Binary files /dev/null and b/assets/templates/shenk/shenk_4.png differ diff --git a/assets/templates/shenk/shenk_5.png b/assets/templates/shenk/shenk_5.png new file mode 100644 index 0000000..3c19808 Binary files /dev/null and b/assets/templates/shenk/shenk_5.png differ diff --git a/assets/templates/shenk/shenk_6.png b/assets/templates/shenk/shenk_6.png new file mode 100644 index 0000000..69a5f3c Binary files /dev/null and b/assets/templates/shenk/shenk_6.png differ diff --git a/assets/templates/shenk/shenk_7.png b/assets/templates/shenk/shenk_7.png new file mode 100644 index 0000000..6f7339d Binary files /dev/null and b/assets/templates/shenk/shenk_7.png differ diff --git a/assets/templates/shenk/shenk_8.png b/assets/templates/shenk/shenk_8.png new file mode 100644 index 0000000..1e9e337 Binary files /dev/null and b/assets/templates/shenk/shenk_8.png differ diff --git a/assets/templates/shenk/shenk_9.png b/assets/templates/shenk/shenk_9.png new file mode 100644 index 0000000..ef1ef03 Binary files /dev/null and b/assets/templates/shenk/shenk_9.png differ diff --git a/src/bot.py b/src/bot.py index e03dade..b12fb17 100644 --- a/src/bot.py +++ b/src/bot.py @@ -246,9 +246,9 @@ class Bot: bot._picked_up_items = bot._pickit.pick_up_items(bot._char) # shenk if bot._route_config["run_shenk"]: - bot._pather.traverse_nodes_fixed("SHENK", bot._char) + bot._pather.traverse_nodes(Location.SHENK_START, Location.SHENK_SAVE_DIST, bot._char) wait(0.15, 0.2) - bot._char.kill_shenk(bot._pather.get_fixed_path("SHENK")[1]) + bot._char.kill_shenk() wait(0.5) bot._picked_up_items |= bot._pickit.pick_up_items(bot._char) self.success = True diff --git a/src/char/hammerdin.py b/src/char/hammerdin.py index 9eb6c86..458efa6 100644 --- a/src/char/hammerdin.py +++ b/src/char/hammerdin.py @@ -49,7 +49,7 @@ class Hammerdin(IChar): mouse.press(button="left") start = time.time() while (time.time() - start) < time_in_s: - time.sleep(0.05) + time.sleep(0.02) mouse.release(button="left") keyboard.send(self._char_config["stand_still"], do_press=False) @@ -59,34 +59,26 @@ class Hammerdin(IChar): def kill_pindle(self) -> bool: wait(0.1, 0.15) - if not self._pather.traverse_nodes(Location.PINDLE_SAVE_DIST, Location.PINDLE_END, self): - return False + self._pather.traverse_nodes(Location.PINDLE_SAVE_DIST, Location.PINDLE_END, self, time_out=0.5) self._cast_hammers(1) # pindle sometimes knocks back, get back in - if not self._pather.traverse_nodes(Location.PINDLE_SAVE_DIST, Location.PINDLE_END, self): - return False + self._pather.traverse_nodes(Location.PINDLE_SAVE_DIST, Location.PINDLE_END, self, time_out=0.2) 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) - keyboard.send(self._skill_hotkeys["teleport"]) - wait(0.05) - custom_mouse.move(pos_monitor[0], pos_monitor[1], duration=(random.random() * 0.05 + 0.15)) - wait(0.02) - mouse.click(button="right") - wait(0.1, 0.15) - self._cast_hammers(6) - wait(0.1, 0.15) - self._do_redemption() - def kill_eldritch(self) -> bool: - if not self._pather.traverse_nodes(Location.ELDRITCH_SAVE_DIST, Location.ELDRITCH_END, self): - return False + self._pather.traverse_nodes(Location.ELDRITCH_SAVE_DIST, Location.ELDRITCH_END, self, time_out=0.2) wait(0.1, 0.15) self._cast_hammers(6) wait(0.1, 0.15) self._do_redemption() return True + + def kill_shenk(self): + self._pather.traverse_nodes(Location.SHENK_SAVE_DIST, Location.SHENK_END, self, time_out=0.2) + wait(0.1, 0.15) + self._cast_hammers(6) + wait(0.1, 0.15) + self._do_redemption() diff --git a/src/char/i_char.py b/src/char/i_char.py index b540127..f26d439 100644 --- a/src/char/i_char.py +++ b/src/char/i_char.py @@ -97,7 +97,7 @@ class IChar: pass @abstract - def kill_shenk(self, shenk_pos_screen): + def kill_shenk(self) -> bool: pass @abstract diff --git a/src/char/sorceress.py b/src/char/sorceress.py index c09c5bf..5fcd771 100644 --- a/src/char/sorceress.py +++ b/src/char/sorceress.py @@ -78,12 +78,11 @@ class Sorceress(IChar): return True return False - def kill_shenk(self, shenk_pos_screen: Tuple[float, float]): + def kill_shenk(self): delay = [0.2, 0.3] - pos_abs = self._screen.convert_screen_to_abs(shenk_pos_screen) + pos_abs = self._pather.find_abs_node_pos(149, self._screen.grab()) 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(shenk_pos_screen) # TODO: Not sure if we need so much attacks... maybe add a "number_attack_sequenze" to the param.ini self._main_attack(cast_pos_monitor, delay, 90) self._left_attack(cast_pos_monitor, delay, 90) @@ -94,9 +93,7 @@ class Sorceress(IChar): 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") + self._pather.traverse_nodes(Location.SHENK_SAVE_DIST, Location.SHENK_END, self, time_out=2.0) def kill_eldritch(self) -> bool: delay = [0.2, 0.3] @@ -111,7 +108,7 @@ class Sorceress(IChar): 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) + self._pather.traverse_nodes(Location.ELDRITCH_SAVE_DIST, Location.ELDRITCH_END, self, time_out=2.0) return True return False diff --git a/src/pather.py b/src/pather.py index da30ef1..15162ab 100644 --- a/src/pather.py +++ b/src/pather.py @@ -31,6 +31,10 @@ class Location: ELDRITCH_START = "eldritch_start" ELDRITCH_SAVE_DIST = "eldritch_save_dist" ELDRITCH_END = "eldritch_end" + # Shenk + SHENK_START = "shenk_start" + SHENK_SAVE_DIST = "shenk_save_dist" + SHENK_END = "shenk_end" class Pather: @@ -45,7 +49,7 @@ class Pather: self._screen = screen self._template_finder = template_finder self._range_x = [-self._config.ui_pos["center_x"] + 10, self._config.ui_pos["center_x"] - 10] - self._range_y = [-self._config.ui_pos["center_y"] + 10, self._config.ui_pos["center_y"] - self._config.ui_pos["skill_bar_height"] - 10] + self._range_y = [-self._config.ui_pos["center_y"] + 10, self._config.ui_pos["center_y"] - self._config.ui_pos["skill_bar_height"] - 50] self._nodes = { # A5 town 0: {"A5_TOWN_0": (110-70, 373), "A5_TOWN_1": (-68-70, -205)}, @@ -72,7 +76,19 @@ class Pather: 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)} + 123: {"ELDRITCH_3": (-148, -498), "ELDRITCH_2": (604, -538), "ELDRITCH_4": (-163, -283)}, + # Shenk + 140: {"SHENK_0": (-224, -340), "SHENK_1": (667, -242)}, + 141: {"SHENK_0": (-194, 66), "SHENK_1": (696, 161), "SHENK_2": (-251, -51)}, + 142: {"SHENK_1": (876, 564), "SHENK_2": (-78, 352), "SHENK_3": (535, -194), "SHENK_4": (-665, -155)}, + 143: {"SHENK_2": (212, 758),"SHENK_3": (823, 209), "SHENK_4": (-377, 248), "SHENK_6": (-508, -103)}, + 144: {"SHENK_6": (-162, 185), "SHENK_7": (721, 226)}, + 145: {"SHENK_12": (146, -200), "SHENK_7": (1204, 558), "SHENK_6": (314, 520), "SHENK_8": (-367, 27)}, + 146: {"SHENK_12": (408, 166), "SHENK_9": (-497, -216), "SHENK_8": (-108, 387)}, + 147: {"SHENK_9": (-100, 208), "SHENK_10": (-646, 100)}, + 148: {"SHENK_9": (451, 395), "SHENK_10": (-97, 282), "SHENK_11": (-459, 208)}, + 149: {"SHENK_11": (532, 602), "SHENK_10": (882, 682), "SHENK_13": (730, 36), "SHENK_14": (510, 343)}, + } self._paths = { # A5 Town @@ -93,14 +109,15 @@ class Pather: # Eldritch (Location.ELDRITCH_START, Location.ELDRITCH_SAVE_DIST): [120, 121, 122], (Location.ELDRITCH_SAVE_DIST, Location.ELDRITCH_END): [123], + # Shenk + (Location.SHENK_START, Location.SHENK_SAVE_DIST): [140, 141, 142, 143, 144, 145, 146, 147, 148], + (Location.SHENK_SAVE_DIST, Location.SHENK_END): [149], } self._fixed_tele_path = { # 0: path to boss, 1: location of boss "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]) } - def get_fixed_path(self, key: str): return self._fixed_tele_path[key] @@ -123,6 +140,7 @@ class Pather: 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) + cv2.putText(img, template_type, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2, cv2.LINE_AA) img = cv2.resize(img, None, fx=0.5, fy=0.5) cv2.imshow("debug", img) cv2.waitKey(1) @@ -151,23 +169,23 @@ class Pather: f = min(f, abs(self._range_x[1] / float(abs_pos[0]))) elif abs_pos[0] < self._range_x[0]: f = min(f, abs(self._range_x[0] / float(abs_pos[0]))) - # Check top y-range + # Check y-range + if abs_pos[1] > self._range_y[1]: + f = min(f, abs(self._range_y[1] / float(abs_pos[1]))) if abs_pos[1] < self._range_y[0]: f = min(f, abs(self._range_y[0] / float(abs_pos[1]))) - # check bottom y-range + globe roi which will also not allow a movement - range_y_bottom = self._range_y[1] - screen_pos = self._screen.convert_abs_to_screen(abs_pos) - if is_in_roi(self._config.ui_roi["mana_globe"], screen_pos) or is_in_roi(self._config.ui_roi["health_globe"], screen_pos): - # convert any of health or mana roi top coordinate to abs (x-coordinate is just a dummy 0 value) - range_y_bottom = self._screen.convert_screen_to_abs((0, self._config.ui_roi["mana_globe"][1]))[1] - if abs_pos[1] > range_y_bottom: - f = min(f, abs(range_y_bottom / float(abs_pos[1]))) # Scale the position by the factor f if f < 1.0: abs_pos = (int(abs_pos[0] * f), int(abs_pos[1] * f)) + # Check if adjusted position is "inside globe" + screen_pos = self._screen.convert_abs_to_screen(abs_pos) + if is_in_roi(self._config.ui_roi["mana_globe"], screen_pos) or is_in_roi(self._config.ui_roi["health_globe"], screen_pos): + # convert any of health or mana roi top coordinate to abs (x-coordinate is just a dummy 0 value) + new_range_y_bottom = self._screen.convert_screen_to_abs((0, self._config.ui_roi["mana_globe"][1]))[1] + f = abs(new_range_y_bottom / float(abs_pos[1])) + abs_pos = (int(abs_pos[0] * f), int(abs_pos[1] * f)) return abs_pos - def find_abs_node_pos(self, node_idx: int, img: np.ndarray) -> Tuple[float, float]: node = self._nodes[node_idx] for template_type in node: @@ -182,13 +200,13 @@ class Pather: return node_pos_abs return None - def traverse_nodes(self, start_location: Location, end_location: Location, char: IChar) -> bool: + def traverse_nodes(self, start_location: Location, end_location: Location, char: IChar, time_out: float = 7) -> bool: """ Traverse from one location to another :param start_location: Location the char is starting at :param end_location: Location the char is supposed to end up :param char: Char that is traversing the nodes - :param debug: Debug mode will display some images and stuff + :param time_out: Timeout in second. If no more move was found in that time it will cancel traverse :return: Bool if traversed succesfull or False if it got stuck """ Logger.debug(f"Traverse from {start_location} to {end_location}") @@ -198,7 +216,7 @@ class Pather: last_move = time.time() while not continue_to_next_node: img = self._screen.grab() - if (time.time() - last_move) > 7: + if (time.time() - last_move) > time_out: success, _ = self._template_finder.search("WAYPOINT_MENU", img) if success: # sometimes bot opens waypoint menu, close it to find templates again @@ -240,4 +258,4 @@ if __name__ == "__main__": 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_debug(filter="ELDRITCH") + pather._display_all_nodes_debug(filter="SHENK") diff --git a/src/template_finder.py b/src/template_finder.py index 59960cf..dcb3ac3 100644 --- a/src/template_finder.py +++ b/src/template_finder.py @@ -44,12 +44,27 @@ 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], - # Teplates for nodes to Eldritch + # Templates 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], + # Templates for nodes to Shenk (from Eldritch) + "SHENK_0": [load_template("assets/templates/shenk/shenk_0.png", self._scale_factor), self._scale_factor], + "SHENK_1": [load_template("assets/templates/shenk/shenk_1.png", self._scale_factor), self._scale_factor], + "SHENK_2": [load_template("assets/templates/shenk/shenk_2.png", self._scale_factor), self._scale_factor], + "SHENK_3": [load_template("assets/templates/shenk/shenk_3.png", self._scale_factor), self._scale_factor], + "SHENK_4": [load_template("assets/templates/shenk/shenk_4.png", self._scale_factor), self._scale_factor], + "SHENK_6": [load_template("assets/templates/shenk/shenk_6.png", self._scale_factor), self._scale_factor], + "SHENK_7": [load_template("assets/templates/shenk/shenk_7.png", self._scale_factor), self._scale_factor], + "SHENK_8": [load_template("assets/templates/shenk/shenk_8.png", self._scale_factor), self._scale_factor], + "SHENK_9": [load_template("assets/templates/shenk/shenk_9.png", self._scale_factor), self._scale_factor], + "SHENK_10": [load_template("assets/templates/shenk/shenk_10.png", self._scale_factor), self._scale_factor], + "SHENK_11": [load_template("assets/templates/shenk/shenk_11.png", self._scale_factor), self._scale_factor], + "SHENK_12": [load_template("assets/templates/shenk/shenk_12.png", self._scale_factor), self._scale_factor], + "SHENK_13": [load_template("assets/templates/shenk/shenk_13.png", self._scale_factor), self._scale_factor], + "SHENK_14": [load_template("assets/templates/shenk/shenk_14.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],