125 lines
5.5 KiB
Python
125 lines
5.5 KiB
Python
from belt_manager import BeltManager
|
|
from ui_manager import UiManager
|
|
from item_finder import ItemFinder
|
|
import time
|
|
from utils.custom_mouse import mouse
|
|
import keyboard
|
|
import cv2
|
|
from config import Config
|
|
from char.i_char import IChar
|
|
from logger import Logger
|
|
from screen import Screen
|
|
from ui_manager import UiManager
|
|
from game_stats import GameStats
|
|
|
|
|
|
class PickIt:
|
|
def __init__(self, screen: Screen, item_finder: ItemFinder, ui_manager: UiManager, belt_manager: BeltManager, game_stats: GameStats = None):
|
|
self._item_finder = item_finder
|
|
self._screen = screen
|
|
self._belt_manager = belt_manager
|
|
self._ui_manager = ui_manager
|
|
self._game_stats = game_stats
|
|
self._config = Config()
|
|
|
|
def pick_up_items(self, char: IChar) -> bool:
|
|
"""
|
|
Pick up all items with specified char
|
|
:param char: The character used to pick up the item
|
|
:return: Bool if any items were picked up or not. (Does not account for picking up scrolls and pots)
|
|
"""
|
|
found_nothing = 0
|
|
found_items = False
|
|
keyboard.send(self._config.char["show_items"])
|
|
time.sleep(1.0) # sleep needed here to give d2r time to display items on screen on keypress
|
|
#Creating a screenshot of the current loot
|
|
if self._config.general["loot_screenshots"]:
|
|
img = self._screen.grab()
|
|
cv2.imwrite("./loot_screenshots/info_debug_drop_" + time.strftime("%Y%m%d_%H%M%S") + ".png", img)
|
|
Logger.debug("Took a screenshot of current loot")
|
|
start = prev_cast_start = time.time()
|
|
time_out = False
|
|
picked_up_items = []
|
|
while not time_out:
|
|
if (time.time() - start) > 24:
|
|
time_out = True
|
|
Logger.warning("Got stuck during pickit, skipping it this time...")
|
|
break
|
|
img = self._screen.grab()
|
|
item_list = self._item_finder.search(img)
|
|
|
|
# Check if we need to pick up certain pots more pots
|
|
need_pots = self._belt_manager.get_pot_needs()
|
|
if need_pots["mana"] <= 0:
|
|
item_list = [x for x in item_list if "mana_potion" not in x.name]
|
|
if need_pots["health"] <= 0:
|
|
item_list = [x for x in item_list if "healing_potion" not in x.name]
|
|
if need_pots["rejuv"] <= 0:
|
|
item_list = [x for x in item_list if "rejuvenation_potion" not in x.name]
|
|
|
|
if len(item_list) == 0:
|
|
# if two times no item was found, break
|
|
found_nothing += 1
|
|
if found_nothing > 1:
|
|
break
|
|
else:
|
|
found_nothing = 0
|
|
closest_item = item_list[0]
|
|
for item in item_list[1:]:
|
|
if closest_item.dist > item.dist:
|
|
closest_item = item
|
|
x_m, y_m = self._screen.convert_screen_to_monitor(closest_item.center)
|
|
if closest_item.dist < self._config.ui_pos["item_dist"]:
|
|
# if potion is picked up, record it in the belt manager
|
|
if "potion" in closest_item.name:
|
|
self._belt_manager.picked_up_pot(closest_item.name)
|
|
# no need to stash potions, scrolls, or gold
|
|
if "potion" not in closest_item.name and "tp_scroll" != closest_item.name and "misc_gold" not in closest_item.name:
|
|
found_items = True
|
|
|
|
Logger.info(f"Picking up: {closest_item.name} ({closest_item.score*100:.1f}% confidence)")
|
|
prev_cast_start = char.pick_up_item((x_m, y_m), item_name=closest_item.name, prev_cast_start=prev_cast_start)
|
|
|
|
if self._ui_manager.is_overburdened():
|
|
Logger.warning("Inventory full, skipping pickit!")
|
|
# TODO: should go back to town and stash stuff then go back to picking up more stuff
|
|
# but sm states are not fine enough for such a routine right now...
|
|
break
|
|
else:
|
|
# send log to discord
|
|
if found_items and closest_item.name not in picked_up_items:
|
|
self._game_stats.log_item_pickup(closest_item.name, self._config.items[closest_item.name] == 2)
|
|
picked_up_items.append(closest_item.name)
|
|
else:
|
|
char.pre_move()
|
|
char.move((x_m, y_m))
|
|
time.sleep(0.1)
|
|
keyboard.send(self._config.char["show_items"])
|
|
return found_items
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import os
|
|
from config import Config
|
|
from char.sorceress import Sorceress
|
|
from ui_manager import UiManager
|
|
from template_finder import TemplateFinder
|
|
from pather import Pather
|
|
from game_stats import GameStats
|
|
import keyboard
|
|
|
|
keyboard.add_hotkey('f12', lambda: Logger.info('Force Exit (f12)') or os._exit(1))
|
|
keyboard.wait("f11")
|
|
config = Config()
|
|
game_states = GameStats()
|
|
screen = Screen(config.general["monitor"])
|
|
t_finder = TemplateFinder(screen)
|
|
ui_manager = UiManager(screen, t_finder)
|
|
belt_manager = BeltManager(screen, t_finder)
|
|
belt_manager._pot_needs = {"rejuv": 0, "health": 2, "mana": 2}
|
|
pather = Pather(screen, t_finder)
|
|
item_finder = ItemFinder()
|
|
char = Sorceress(config.sorceress, config.char, screen, t_finder, ui_manager, pather)
|
|
pickit = PickIt(screen, item_finder, ui_manager, belt_manager, game_states)
|
|
pickit.pick_up_items(char)
|