Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1f2cad291 | ||
|
|
285e635b0d | ||
|
|
54203ff036 | ||
|
|
6b378a4606 | ||
|
|
9707fc4563 | ||
|
|
1a4e6c9533 | ||
|
|
fb22b86d11 | ||
|
|
3c3f95142d | ||
|
|
029b8dcdc6 | ||
|
|
400d43c49c |
@@ -45,5 +45,6 @@
|
||||
"Always Run": 1,
|
||||
"Quick Cast Enabled": 0,
|
||||
"Display Active Skill Bindings": 0,
|
||||
"Lobby Wide Item Drop Enabled": 1
|
||||
"Lobby Wide Item Drop Enabled": 1,
|
||||
"Item Tooltip Hotkey Appender": 1
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
@@ -129,6 +129,7 @@ left_panel_header=0,0,450,54
|
||||
right_panel_header=830,0,450,54
|
||||
npc_dialogue=458,4,21,140
|
||||
bind_skill=516,619,251,29
|
||||
quest_skill_btn=284,455,710,121
|
||||
|
||||
[path]
|
||||
; static pathes in format: x0,y0, x1,y1, x2,y2, ...
|
||||
|
||||
@@ -331,7 +331,7 @@ class Bot:
|
||||
return self.trigger_or_stop("end_game", failed=True)
|
||||
|
||||
# Stash stuff
|
||||
if keep_items:
|
||||
if keep_items or personal.get_inventory_gold_full():
|
||||
Logger.info("Stashing items")
|
||||
self._curr_loc, result_items = self._town_manager.stash(self._curr_loc, items=items)
|
||||
Logger.info("Running transmutes")
|
||||
|
||||
@@ -170,7 +170,6 @@ class Config:
|
||||
self.items["misc_gold"].pickit_type = 1
|
||||
|
||||
def load_data(self):
|
||||
Logger.info("Loading Config Data")
|
||||
self._config = configparser.ConfigParser()
|
||||
self._config.read('config/params.ini')
|
||||
self._game_config = configparser.ConfigParser()
|
||||
|
||||
@@ -12,7 +12,7 @@ from game_stats import GameStats
|
||||
from health_manager import HealthManager
|
||||
from logger import Logger
|
||||
from messages import Messenger
|
||||
from screen import grab, found_offsets
|
||||
from screen import grab, get_offset_state
|
||||
from utils.restart import restart_game, kill_game
|
||||
from utils.misc import kill_thread, set_d2r_always_on_top, restore_d2r_window_visibility
|
||||
|
||||
@@ -121,7 +121,7 @@ class GameController:
|
||||
self.is_running = False
|
||||
|
||||
def setup_screen(self):
|
||||
if found_offsets:
|
||||
if get_offset_state():
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@@ -76,9 +76,7 @@ class HealthManager:
|
||||
# Wait until the flag is reset by main.py
|
||||
if self._did_chicken or self._pausing: continue
|
||||
img = grab()
|
||||
# TODO: Check if in town or not! Otherwise risk endless chicken loop
|
||||
match = detect_screen_object(ScreenObjects.InGame, img)
|
||||
if match.valid:
|
||||
if detect_screen_object(ScreenObjects.InGame, img).valid:
|
||||
health_percentage = meters.get_health(img)
|
||||
mana_percentage = meters.get_mana(img)
|
||||
# check rejuv
|
||||
@@ -105,8 +103,7 @@ class HealthManager:
|
||||
belt.drink_potion("mana", stats=[health_percentage, mana_percentage])
|
||||
self._last_mana = time.time()
|
||||
# check merc
|
||||
match = detect_screen_object(ScreenObjects.MercIcon)
|
||||
if match.valid:
|
||||
if detect_screen_object(ScreenObjects.MercIcon, img).valid:
|
||||
merc_health_percentage = meters.get_merc_health(img)
|
||||
last_drink = time.time() - self._last_merc_heal
|
||||
if merc_health_percentage < Config().char["merc_chicken"]:
|
||||
@@ -118,6 +115,9 @@ class HealthManager:
|
||||
elif merc_health_percentage < Config().char["heal_merc"] and last_drink > 7.0:
|
||||
belt.drink_potion("health", merc=True, stats=[merc_health_percentage])
|
||||
self._last_merc_heal = time.time()
|
||||
if detect_screen_object(ScreenObjects.QuestSkillBtn, img).valid:
|
||||
Logger.warning(f"Skill, stats, or quest button appeared--quit to avoid accidental allocations.")
|
||||
self._do_chicken(img)
|
||||
Logger.debug("Stop health monitoring")
|
||||
|
||||
|
||||
|
||||
@@ -144,6 +144,7 @@ def transfer_items(items: list, action: str = "drop") -> list:
|
||||
wait(0.2, 0.4)
|
||||
for item in filtered:
|
||||
attempts = 0
|
||||
prev_gold_img = cut_roi(grab(), roi=Config().ui_roi["inventory_gold_digits"])
|
||||
while attempts < 2:
|
||||
# move to item position and left click
|
||||
mouse.move(*item.pos, randomize=4, delay_factor=[0.2, 0.4])
|
||||
@@ -159,15 +160,23 @@ def transfer_items(items: list, action: str = "drop") -> list:
|
||||
mouse.press(button="left")
|
||||
wait(0.2, 0.3)
|
||||
mouse.release(button="left")
|
||||
wait(0.2, 0.3)
|
||||
wait(0.8, 1)
|
||||
# check if item is still there
|
||||
slot_img = get_slot_pos_and_img(grab(), item.column, item.row)[1]
|
||||
img=grab()
|
||||
slot_img = get_slot_pos_and_img(img, item.column, item.row)[1]
|
||||
if not slot_has_item(slot_img):
|
||||
# item successfully transferred, delete from list
|
||||
for cnt, o_item in enumerate(items):
|
||||
if o_item.pos == item.pos:
|
||||
items.pop(cnt)
|
||||
break
|
||||
# check and see if inventory gold count changed
|
||||
new_gold_img = cut_roi(img, roi=Config().ui_roi["inventory_gold_digits"])
|
||||
if prev_gold_img.shape == new_gold_img.shape and not(np.bitwise_xor(prev_gold_img, new_gold_img).any()):
|
||||
Logger.info("Inventory gold is full, force stash")
|
||||
personal.set_inventory_gold_full(True)
|
||||
else:
|
||||
personal.set_inventory_gold_full(False)
|
||||
break
|
||||
else:
|
||||
# item is still there, try again
|
||||
|
||||
@@ -19,10 +19,19 @@ from ui_manager import detect_screen_object, wait_for_screen_object, ScreenObjec
|
||||
from item import ItemCropper
|
||||
from messages import Messenger
|
||||
|
||||
inv_gold_full = False
|
||||
messenger = Messenger()
|
||||
item_finder = ItemFinder()
|
||||
nontradable_items = ["key of ", "essense of", "wirt's", "jade figurine"]
|
||||
|
||||
def get_inventory_gold_full():
|
||||
global inv_gold_full
|
||||
return inv_gold_full
|
||||
|
||||
def set_inventory_gold_full(bool):
|
||||
global inv_gold_full
|
||||
inv_gold_full = bool
|
||||
|
||||
def inventory_has_items(img: np.ndarray = None, close_window = False) -> bool:
|
||||
"""
|
||||
Check if Inventory has any items
|
||||
@@ -61,7 +70,7 @@ def stash_all_items(items: list = None):
|
||||
if Config().char["stash_gold"]:
|
||||
img = grab()
|
||||
if detect_screen_object(ScreenObjects.GoldNone, img).valid:
|
||||
Logger.debug("Skipping gold stashing")
|
||||
Logger.debug("No gold to stash")
|
||||
else:
|
||||
Logger.debug("Stashing gold")
|
||||
stash.move_to_stash_tab(min(3, stash.curr_stash["gold"]))
|
||||
@@ -69,6 +78,8 @@ def stash_all_items(items: list = None):
|
||||
# Try to read gold count with OCR
|
||||
stash_full_of_gold = common.read_gold(img, "stash") == 2500000
|
||||
except:
|
||||
stash_full_of_gold = False
|
||||
if not stash_full_of_gold:
|
||||
# If gold read by OCR fails, fallback to old method
|
||||
mouse.move(*gold_btn.center, randomize=4)
|
||||
wait(0.1, 0.15)
|
||||
@@ -93,6 +104,8 @@ def stash_all_items(items: list = None):
|
||||
# move to next stash
|
||||
wait(0.5, 0.6)
|
||||
return stash_all_items(items=items)
|
||||
else:
|
||||
set_inventory_gold_full(False)
|
||||
# check if stash tab is completely full (no empty slots)
|
||||
stash.move_to_stash_tab(stash.curr_stash["items"])
|
||||
while stash.curr_stash["items"] <= 3:
|
||||
|
||||
@@ -5,16 +5,17 @@ import os
|
||||
from utils.misc import wait
|
||||
from utils.custom_mouse import mouse
|
||||
from logger import Logger
|
||||
from messages import Messenger
|
||||
|
||||
curr_stash = {
|
||||
"items": 3 if Config().char["fill_shared_stash_first"] else 0,
|
||||
"gold": 0
|
||||
}
|
||||
|
||||
def stash_full(self):
|
||||
def stash_full():
|
||||
Logger.error("All stash is full, quitting")
|
||||
if self._config.general["custom_message_hook"]:
|
||||
self._messenger.send_stash()
|
||||
if Config().general["custom_message_hook"]:
|
||||
Messenger().send_stash()
|
||||
os.system("taskkill /f /im D2R.exe")
|
||||
wait(1.0, 1.5)
|
||||
os._exit(0)
|
||||
|
||||
@@ -4,11 +4,11 @@ from template_finder import TemplateFinder
|
||||
from config import Config
|
||||
import numpy as np
|
||||
from utils.misc import wait
|
||||
from screen import convert_screen_to_monitor, grab
|
||||
from screen import grab
|
||||
from logger import Logger
|
||||
from utils.custom_mouse import mouse
|
||||
from ui_manager import detect_screen_object, wait_for_screen_object, ScreenObjects
|
||||
from inventory import personal, stash, common
|
||||
from inventory import personal, common
|
||||
|
||||
gamble_count = 0
|
||||
gamble_status = False
|
||||
@@ -92,6 +92,7 @@ def gamble():
|
||||
if new_count >= max_gamble_count:
|
||||
break
|
||||
Logger.debug(f"Finish gambling")
|
||||
personal.set_inventory_gold_full(False)
|
||||
set_gamble_status(False)
|
||||
common.close()
|
||||
return None
|
||||
@@ -122,6 +123,7 @@ def buy_item(template_name: str, quantity: int = 1, img: np.ndarray = None, shif
|
||||
keyboard.send("esc")
|
||||
return False
|
||||
keyboard.send('shift', do_release=True)
|
||||
personal.set_inventory_gold_full(False)
|
||||
return True
|
||||
if quantity:
|
||||
for _ in range(quantity):
|
||||
@@ -131,6 +133,7 @@ def buy_item(template_name: str, quantity: int = 1, img: np.ndarray = None, shif
|
||||
Logger.warning(f"Out of gold, could not purchase {template_name}")
|
||||
keyboard.send("esc")
|
||||
return False
|
||||
personal.set_inventory_gold_full(False)
|
||||
return True
|
||||
else:
|
||||
Logger.error("buy_item: Quantity not specified")
|
||||
|
||||
@@ -112,7 +112,7 @@ class ItemCropper:
|
||||
x, y, w, h = cv2.boundingRect(cntr)
|
||||
cropped_item = inp_img[y:y+h, x:x+w]
|
||||
avg = np.average(cv2.cvtColor(cropped_item, cv2.COLOR_BGR2GRAY))
|
||||
mostly_dark = True if 0 < avg < 20 else False
|
||||
mostly_dark = True if 0 < avg < 25 else False
|
||||
contains_black = True if np.min(cropped_item) < 14 else False
|
||||
contains_white = True if np.max(cropped_item) > 250 else False
|
||||
contains_orange = False
|
||||
|
||||
@@ -2,13 +2,13 @@ import logging
|
||||
import io
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import warnings
|
||||
from version import __version__
|
||||
|
||||
class Logger:
|
||||
"""Manage logging"""
|
||||
_logger_level = None
|
||||
_formatter = logging.Formatter('[%(asctime)s] %(levelname)-10s %(message)s')
|
||||
_formatter = logging.Formatter(f'[{__version__} %(asctime)s] %(levelname)-10s %(message)s')
|
||||
_log_contents = io.StringIO()
|
||||
_current_log_file_path = "info.log"
|
||||
_output = "" # intercepted output from stdout and stderr
|
||||
@@ -22,7 +22,7 @@ class Logger:
|
||||
if Logger.logger is None:
|
||||
Logger.init()
|
||||
Logger.logger.debug(data)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def info(data: str):
|
||||
if Logger.logger is None:
|
||||
@@ -82,7 +82,7 @@ class Logger:
|
||||
Logger.logger.addHandler(Logger.string_handler)
|
||||
Logger.logger.addHandler(Logger.console_handler)
|
||||
Logger.logger.addHandler(Logger.file_handler)
|
||||
|
||||
|
||||
# redirect stderr & stdout to logger, e.g. print("...")
|
||||
# would have to implement all the std func such as write() flush() etc.
|
||||
# sys.stderr = Logger
|
||||
|
||||
@@ -48,7 +48,6 @@ def main():
|
||||
GameController(),
|
||||
GraphicDebuggerController()
|
||||
)
|
||||
screen.start_detecting_window()
|
||||
if Config().advanced_options["logg_lvl"] == "info":
|
||||
Logger.init(logging.INFO)
|
||||
elif Config().advanced_options["logg_lvl"] == "debug":
|
||||
|
||||
@@ -19,16 +19,20 @@ FIND_WINDOW = WindowSpec(
|
||||
process_name_regex=Config().advanced_options["hwnd_window_process"],
|
||||
)
|
||||
|
||||
def get_offset_state():
|
||||
global found_offsets
|
||||
return found_offsets
|
||||
|
||||
def start_detecting_window():
|
||||
global detect_window, detect_window_thread
|
||||
detect_window = True
|
||||
if detect_window_thread is None:
|
||||
Logger.debug(f"Using WinAPI to search for window: {FIND_WINDOW}")
|
||||
detect_window_thread = threading.Thread(target=detect_window_position)
|
||||
detect_window_thread.start()
|
||||
|
||||
def detect_window_position():
|
||||
global detect_window
|
||||
Logger.debug('Detect window thread started')
|
||||
while detect_window:
|
||||
find_and_set_window_position()
|
||||
Logger.debug('Detect window thread stopped')
|
||||
@@ -38,7 +42,7 @@ def find_and_set_window_position():
|
||||
).advanced_options["window_client_area_offset"])
|
||||
if position is not None:
|
||||
set_window_position(*position)
|
||||
wait(0.5)
|
||||
wait(1)
|
||||
|
||||
def set_window_position(offset_x: int, offset_y: int):
|
||||
global monitor_roi, monitor_x_range, monitor_y_range, found_offsets
|
||||
@@ -105,5 +109,3 @@ def convert_abs_to_monitor(abs_coord: Tuple[float, float]) -> Tuple[float, float
|
||||
screen_coord = convert_abs_to_screen(abs_coord)
|
||||
monitor_coord = convert_screen_to_monitor(screen_coord)
|
||||
return monitor_coord
|
||||
|
||||
Logger.debug(f"Using WinAPI to search for window: {FIND_WINDOW}")
|
||||
|
||||
@@ -32,11 +32,11 @@ class A1(IAct):
|
||||
return False
|
||||
|
||||
def open_wp(self, curr_loc: Location) -> bool:
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A1_WP_SOUTH), self._char): return False
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A1_WP_SOUTH), self._char, force_move=True): return False
|
||||
wait(0.5, 0.7)
|
||||
if not TemplateFinder().search("A1_WP", grab()).valid:
|
||||
curr_loc = Location.A1_WP_SOUTH
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A1_WP_NORTH), self._char): return False
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A1_WP_NORTH), self._char, force_move=True): return False
|
||||
wait(0.5, 0.7)
|
||||
found_wp_func = lambda: detect_screen_object(ScreenObjects.WaypointLabel).valid
|
||||
# decreased threshold because we sometimes walk "over" it during pathing
|
||||
@@ -50,7 +50,7 @@ class A1(IAct):
|
||||
return False
|
||||
|
||||
def identify(self, curr_loc: Location) -> Union[Location, bool]:
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A1_KASHYA_CAIN), self._char): return False
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A1_KASHYA_CAIN), self._char, force_move=True): return False
|
||||
if open_npc_menu(Npc.CAIN):
|
||||
press_npc_btn(Npc.CAIN, "identify")
|
||||
return Location.A1_KASHYA_CAIN
|
||||
@@ -63,7 +63,7 @@ class A1(IAct):
|
||||
return Location.A1_AKARA
|
||||
|
||||
def open_stash(self, curr_loc: Location) -> Union[Location, bool]:
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A1_STASH), self._char):
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A1_STASH), self._char, force_move=True):
|
||||
return False
|
||||
wait(0.5, 0.6)
|
||||
def stash_is_open_func():
|
||||
@@ -81,7 +81,7 @@ class A1(IAct):
|
||||
return Location.A1_AKARA
|
||||
|
||||
def open_trade_and_repair_menu(self, curr_loc: Location) -> Union[Location, bool]:
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A1_CHARSI), self._char): return False
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A1_CHARSI), self._char, force_move=True): return False
|
||||
open_npc_menu(Npc.CHARSI)
|
||||
press_npc_btn(Npc.CHARSI, "trade_repair")
|
||||
return Location.A1_CHARSI
|
||||
|
||||
@@ -61,7 +61,7 @@ class A3(IAct):
|
||||
return False
|
||||
|
||||
def identify(self, curr_loc: Location) -> Union[Location, bool]:
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A3_STASH_WP), self._char): return False
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A3_STASH_WP), self._char, force_move=True): return False
|
||||
if open_npc_menu(Npc.CAIN):
|
||||
press_npc_btn(Npc.CAIN, "identify")
|
||||
return Location.A3_STASH_WP
|
||||
|
||||
@@ -33,7 +33,7 @@ class A4(IAct):
|
||||
return False
|
||||
|
||||
def open_wp(self, curr_loc: Location) -> bool:
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A4_WP), self._char): return False
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A4_WP), self._char, force_move=True): return False
|
||||
wait(0.5, 0.7)
|
||||
found_wp_func = lambda: detect_screen_object(ScreenObjects.WaypointLabel).valid
|
||||
# decreased threshold because we sometimes walk "over" it during pathing
|
||||
@@ -86,7 +86,7 @@ class A4(IAct):
|
||||
return False
|
||||
|
||||
def open_trade_and_repair_menu(self, curr_loc: Location) -> Union[Location, bool]:
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A4_HALBU), self._char): return False
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A4_HALBU), self._char, force_move=True): return False
|
||||
if open_npc_menu(Npc.HALBU):
|
||||
press_npc_btn(Npc.HALBU, "trade_repair")
|
||||
return Location.A4_HALBU
|
||||
|
||||
@@ -37,21 +37,21 @@ class A5(IAct):
|
||||
return False
|
||||
|
||||
def resurrect(self, curr_loc: Location) -> Union[Location, bool]:
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A5_QUAL_KEHK), self._char): return False
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A5_QUAL_KEHK), self._char, force_move=True): return False
|
||||
if open_npc_menu(Npc.QUAL_KEHK):
|
||||
press_npc_btn(Npc.QUAL_KEHK, "resurrect")
|
||||
return Location.A5_QUAL_KEHK
|
||||
return False
|
||||
|
||||
def identify(self, curr_loc: Location) -> Union[Location, bool]:
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A5_QUAL_KEHK), self._char): return False
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A5_QUAL_KEHK), self._char, force_move=True): return False
|
||||
if open_npc_menu(Npc.CAIN):
|
||||
press_npc_btn(Npc.CAIN, "identify")
|
||||
return Location.A5_QUAL_KEHK
|
||||
return False
|
||||
|
||||
def open_stash(self, curr_loc: Location) -> Union[Location, bool]:
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A5_STASH), self._char):
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A5_STASH), self._char, force_move=True):
|
||||
return False
|
||||
wait(0.5, 0.6)
|
||||
def stash_is_open_func():
|
||||
@@ -64,13 +64,13 @@ class A5(IAct):
|
||||
return Location.A5_STASH
|
||||
|
||||
def open_trade_and_repair_menu(self, curr_loc: Location) -> Union[Location, bool]:
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A5_LARZUK), self._char): return False
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A5_LARZUK), self._char, force_move=True): return False
|
||||
open_npc_menu(Npc.LARZUK)
|
||||
press_npc_btn(Npc.LARZUK, "trade_repair")
|
||||
return Location.A5_LARZUK
|
||||
|
||||
def open_wp(self, curr_loc: Location) -> bool:
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A5_WP), self._char): return False
|
||||
if not self._pather.traverse_nodes((curr_loc, Location.A5_WP), self._char, force_move=True): return False
|
||||
wait(0.5, 0.7)
|
||||
found_wp_func = lambda: detect_screen_object(ScreenObjects.WaypointLabel).valid
|
||||
return self._char.select_by_template("A5_WP", found_wp_func, telekinesis=True)
|
||||
|
||||
@@ -5,6 +5,7 @@ from pather import Location
|
||||
from logger import Logger
|
||||
from town import IAct, A1, A2, A3, A4, A5
|
||||
from utils.misc import wait
|
||||
from screen import grab
|
||||
from ui import waypoint, view
|
||||
from inventory import consumables, personal, vendor, common
|
||||
|
||||
@@ -97,41 +98,42 @@ class TownManager:
|
||||
if self._acts[curr_act].can_buy_pots():
|
||||
new_loc = self._acts[curr_act].open_trade_menu(curr_loc)
|
||||
if not new_loc: return False, items
|
||||
img=grab()
|
||||
# Buy HP pots
|
||||
if consumables.get_needs("health") > 0:
|
||||
can_shift_click = not sum([ x > 0 for x in [consumables.get_needs("health"), consumables.get_needs("mana"), consumables.get_needs("rejuv")]]) > 1
|
||||
if vendor.buy_item(template_name = "SUPER_HEALING_POTION", quantity = consumables.get_needs("health"), shift_click = can_shift_click):
|
||||
if vendor.buy_item(template_name = "SUPER_HEALING_POTION", quantity = consumables.get_needs("health"), shift_click = can_shift_click, img=img):
|
||||
consumables.set_needs("health", 0)
|
||||
else:
|
||||
if vendor.buy_item(template_name="GREATER_HEALING_POTION", quantity = consumables.get_needs("health"), shift_click = can_shift_click):
|
||||
if vendor.buy_item(template_name="GREATER_HEALING_POTION", quantity = consumables.get_needs("health"), shift_click = can_shift_click, img=img):
|
||||
consumables.set_needs("health", 0)
|
||||
else:
|
||||
Logger.error("buy_consumables: Error purchasing health potions")
|
||||
# Buy mana pots
|
||||
if consumables.get_needs("mana") > 0:
|
||||
can_shift_click = not sum([ x > 0 for x in [consumables.get_needs("health"), consumables.get_needs("mana"), consumables.get_needs("rejuv")]]) > 1
|
||||
if vendor.buy_item(template_name="SUPER_MANA_POTION", quantity = consumables.get_needs("mana"), shift_click = can_shift_click):
|
||||
if vendor.buy_item(template_name="SUPER_MANA_POTION", quantity = consumables.get_needs("mana"), shift_click = can_shift_click, img=img):
|
||||
consumables.set_needs("mana", 0)
|
||||
else:
|
||||
if vendor.buy_item(template_name="GREATER_MANA_POTION", quantity = consumables.get_needs("mana"), shift_click = can_shift_click):
|
||||
if vendor.buy_item(template_name="GREATER_MANA_POTION", quantity = consumables.get_needs("mana"), shift_click = can_shift_click, img=img):
|
||||
consumables.set_needs("mana", 0)
|
||||
else:
|
||||
Logger.error("buy_consumables: Error purchasing mana potions")
|
||||
# Buy TP scrolls
|
||||
if consumables.get_needs("tp") > 0:
|
||||
if vendor.buy_item(template_name="INV_SCROLL_TP", shift_click = True):
|
||||
if vendor.buy_item(template_name="INV_SCROLL_TP", shift_click = True, img=img):
|
||||
consumables.set_needs("tp", 0)
|
||||
else:
|
||||
Logger.error("buy_consumables: Error purchasing teleport scrolls")
|
||||
# Buy ID scrolls
|
||||
if consumables.get_needs("id") > 0:
|
||||
if vendor.buy_item(template_name="INV_SCROLL_ID", shift_click = True):
|
||||
if vendor.buy_item(template_name="INV_SCROLL_ID", shift_click = True, img=img):
|
||||
consumables.set_needs("id", 0)
|
||||
else:
|
||||
Logger.error("buy_consumables: Error purchasing ID scrolls")
|
||||
# Buy keys
|
||||
if consumables.get_needs("key") > 0:
|
||||
if vendor.buy_item(template_name="INV_KEY", shift_click = True):
|
||||
if vendor.buy_item(template_name="INV_KEY", shift_click = True, img=img):
|
||||
consumables.set_needs("key", 0)
|
||||
else:
|
||||
Logger.error("buy_consumables: Error purchasing keys")
|
||||
|
||||
@@ -262,6 +262,12 @@ class ScreenObjects:
|
||||
color_match=Config().colors["red"],
|
||||
use_grayscale=True
|
||||
)
|
||||
QuestSkillBtn=ScreenObject(
|
||||
ref="QUEST_SKILL_BTN",
|
||||
threshold=0.9,
|
||||
use_grayscale=True,
|
||||
roi="quest_skill_btn"
|
||||
)
|
||||
|
||||
def detect_screen_object(screen_object: ScreenObject, img: np.ndarray = None) -> TemplateMatch:
|
||||
roi = Config().ui_roi[screen_object.roi] if screen_object.roi else None
|
||||
|
||||
@@ -4,7 +4,7 @@ import keyboard
|
||||
from bot import Bot
|
||||
from template_finder import TemplateFinder
|
||||
from utils.misc import wait, set_d2r_always_on_top
|
||||
from screen import found_offsets, grab
|
||||
from screen import get_offset_state, grab
|
||||
from config import Config
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ def restart_game(d2_path = None):
|
||||
attempts = 0
|
||||
set_d2r_always_on_top()
|
||||
while not success:
|
||||
success = found_offsets
|
||||
success = get_offset_state()
|
||||
wait(0.5, 1.0)
|
||||
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = '0.7.0-dev'
|
||||
__version__ = '0.7.1'
|
||||